org.treeingwalker.LessCompilerTest.java Source code

Java tutorial

Introduction

Here is the source code for org.treeingwalker.LessCompilerTest.java

Source

/* Copyright 2011-2012 The Apache Software Foundation.
 *
 * 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 org.treeingwalker;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mozilla.javascript.*;
import org.mozilla.javascript.tools.shell.Global;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.treeingwalker.logging.LessLogger;

import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.verify;
import static org.powermock.api.mockito.PowerMockito.*;

@PrepareForTest({ Context.class, FileUtils.class, LessCompiler.class })
@RunWith(PowerMockRunner.class)
public class LessCompilerTest {

    private static final String COMPILE_STRING = "function doIt(input, compress) { var result; var parser = new less.Parser(); parser.parse(input, function(e, tree) { if (e instanceof Object) { throw e; } ; result = tree.toCSS({compress: compress}); }); return result; }";

    private LessCompiler lessCompiler;

    @Mock
    private LessLogger logger;

    @Mock
    private Context cx;
    @Mock
    private Global global;
    @Mock
    private Scriptable scope;
    @Mock
    private InterpretedFunction compiler;

    @Mock
    private URL envJsFile;
    @Mock
    private URLConnection envJsURLConnection;
    private static final String envJsURLToString = "env.rhino.js";
    @Mock
    private InputStream envJsInputStream;
    @Mock
    private InputStreamReader envJsInputStreamReader;

    @Mock
    private URL lessJsFile;
    @Mock
    private URLConnection lessJsURLConnection;
    private static final String lessJsURLToString = "less-rhino-1.7.0.js";
    @Mock
    private InputStream lessJsInputStream;
    @Mock
    private InputStreamReader lessJsInputStreamReader;

    @Mock
    private File inputFile;
    @Mock
    private File outputFile;
    @Mock
    private LessSource lessSource;

    @Mock
    private ScriptableObject compileScope;
    @Mock
    private ByteArrayOutputStream out;

    private String less = "less";
    private String css = "css";

    public abstract static class InterpretedFunction implements Script, Function {
    }

    @Before
    public void setUp() throws Exception {
        lessCompiler = new LessCompiler();

        when(logger.isDebugEnabled()).thenReturn(false);
        FieldUtils.writeField(lessCompiler, "logger", logger, true);
    }

    @Test
    public void testNewLessCompiler() throws Exception {
        assertEquals(LessCompiler.class.getClassLoader().getResource("META-INF/less-rhino-1.7.0.js"),
                FieldUtils.readField(lessCompiler, "lessJs", true));
        assertEquals(LessCompiler.class.getClassLoader().getResource("META-INF/lessc-rhino-1.7.0.js"),
                FieldUtils.readField(lessCompiler, "lesscJs", true));
        assertEquals(Collections.EMPTY_LIST, FieldUtils.readField(lessCompiler, "customJs", true));
    }

    @Test(expected = IllegalArgumentException.class)
    public void testSetEnvJs() throws Exception {
        URL envJsFile = new File("my-env.js").toURI().toURL();
        lessCompiler.setEnvJs(envJsFile);
        assertEquals(envJsFile, lessCompiler.getEnvJs());
    }

    @Test
    public void testSetLessJs() throws Exception {
        URL lessJsFile = new File("my-less.js").toURI().toURL();
        lessCompiler.setLessJs(lessJsFile);
        assertEquals(lessJsFile, lessCompiler.getLessJs());
    }

    @Test
    public void testSetCustomJs() throws Exception {
        URL customJsFile = new File("my-custom.js").toURI().toURL();
        lessCompiler.setCustomJs(customJsFile);
        assertEquals(1, lessCompiler.getCustomJs().size());
        assertTrue(lessCompiler.getCustomJs().contains(customJsFile));
    }

    @Test
    public void testSetCustomJsList() throws Exception {
        URL customJsFile1 = new File("my-custom-1.js").toURI().toURL();
        URL customJsFile2 = new File("my-custom-2.js").toURI().toURL();
        List<URL> customJsFiles = Arrays.asList(customJsFile1, customJsFile2);
        lessCompiler.setCustomJs(customJsFiles);
        assertEquals(2, lessCompiler.getCustomJs().size());
        assertEquals(customJsFile1, lessCompiler.getCustomJs().get(0));
        assertEquals(customJsFile2, lessCompiler.getCustomJs().get(1));
    }

    @Test
    public void testInit() throws Exception {
        mockStatic(Context.class);
        when(Context.enter()).thenReturn(cx);

        whenNew(Global.class).withNoArguments().thenReturn(global);

        when(cx.initStandardObjects(global)).thenReturn(scope);
        when(cx.compileReader(lessJsInputStreamReader, lessJsURLToString, 1, null)).thenReturn(compiler);

        when(envJsFile.openConnection()).thenReturn(envJsURLConnection);
        when(envJsFile.toString()).thenReturn(envJsURLToString);
        when(envJsURLConnection.getInputStream()).thenReturn(envJsInputStream);
        whenNew(InputStreamReader.class).withArguments(envJsInputStream).thenReturn(envJsInputStreamReader);

        when(lessJsFile.openConnection()).thenReturn(lessJsURLConnection);
        when(lessJsFile.toString()).thenReturn(lessJsURLToString);
        when(lessJsURLConnection.getInputStream()).thenReturn(lessJsInputStream);
        whenNew(InputStreamReader.class).withArguments(lessJsInputStream).thenReturn(lessJsInputStreamReader);

        lessCompiler.setLessJs(lessJsFile);
        lessCompiler.init();

        verifyStatic();
        Context.enter();
        //verify(cx).setOptimizationLevel(-1);
        verify(cx).setLanguageVersion(Context.VERSION_1_7);

        verifyNew(Global.class).withNoArguments();
        verify(global).init(cx);

        // verify(envJsFile).openConnection();
        //verify(envJsURLConnection).getInputStream();
        //verifyNew(InputStreamReader.class).withArguments(envJsInputStream);
        //verify(cx).evaluateReader(scope, envJsInputStreamReader, envJsURLToString, 1, null);

        // verify(lessJsFile).openConnection();
        verify(lessJsURLConnection).getInputStream();
        verify(cx).compileReader(null, lessJsURLToString, 1, null);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testInitThrowsIllegalArgumentExceptionWhenNotAbleToInitilize() throws Exception {
        mockStatic(Context.class);
        when(Context.enter()).thenReturn(cx);

        whenNew(Global.class).withNoArguments().thenReturn(global);

        when(cx.initStandardObjects(global)).thenReturn(scope);
        when(cx.compileReader(lessJsInputStreamReader, lessJsURLToString, 1, null)).thenReturn(compiler);

        when(envJsFile.openConnection()).thenThrow(new IOException());

        lessCompiler.setEnvJs(envJsFile);
        lessCompiler.setLessJs(lessJsFile);
        lessCompiler.init();

        verifyStatic();
        Context.enter();
        verify(cx).setOptimizationLevel(-1);
        verify(cx).setLanguageVersion(Context.VERSION_1_7);

        verifyNew(Global.class).withNoArguments();
        verify(global).init(cx);

        verify(envJsFile).openConnection();

        verify(logger).error(anyString(), (Throwable) anyObject());
    }

    @Test
    public void testCompileStringWhenNotInitialized() throws Exception {
        mockStatic(Context.class);
        when(Context.enter()).thenReturn(cx);

        whenNew(Global.class).withNoArguments().thenReturn(global);

        when(cx.initStandardObjects(global)).thenReturn(scope);
        when(cx.compileReader(null, lessJsURLToString, 1, null)).thenReturn(compiler);

        when(envJsFile.openConnection()).thenReturn(envJsURLConnection);
        when(envJsFile.toString()).thenReturn(envJsURLToString);
        when(envJsURLConnection.getInputStream()).thenReturn(envJsInputStream);

        when(lessJsFile.openConnection()).thenReturn(lessJsURLConnection);
        when(lessJsFile.toString()).thenReturn(lessJsURLToString);
        when(lessJsURLConnection.getInputStream()).thenReturn(lessJsInputStream);
        whenNew(InputStreamReader.class).withArguments(lessJsInputStream).thenReturn(lessJsInputStreamReader);

        when(cx.newObject(scope)).thenReturn(compileScope);
        whenNew(ByteArrayOutputStream.class).withNoArguments().thenReturn(out);
        when(out.toString()).thenReturn(css);

        lessCompiler.setLessJs(lessJsFile);

        assertEquals(css, lessCompiler.compile(less));

        //verifyStatic();
        //verify(cx).setOptimizationLevel(-1);
        verify(cx).setLanguageVersion(Context.VERSION_1_7);

        verifyNew(Global.class).withNoArguments();
        verify(global).init(cx);

        // verify(envJsFile).openConnection();
        //verify(envJsURLConnection).getInputStream();
        //verifyNew(InputStreamReader.class).withArguments(envJsInputStream);
        //verify(cx).evaluateReader(scope, envJsInputStreamReader, envJsURLToString, 1, null);

        // verify(lessJsFile).openConnection();
        verify(lessJsURLConnection).getInputStream();
        verify(cx).compileReader(null, lessJsURLToString, 1, null);

        verify(compiler).call(cx, compileScope, null, new Object[] {});
    }

    @Test
    public void testCompileStringToString() throws Exception {
        mockStatic(Context.class);
        when(Context.enter()).thenReturn(cx);
        FieldUtils.writeField(lessCompiler, "scope", scope, true);
        FieldUtils.writeField(lessCompiler, "compiler", compiler, true);
        FieldUtils.writeField(lessCompiler, "out", out, true);
        when(cx.newObject(scope)).thenReturn(compileScope);

        when(out.toString()).thenReturn(css);

        assertEquals(css, lessCompiler.compile(less));

        verify(compiler).call(cx, compileScope, null, new Object[] {});
    }

    @Test
    public void testCompileFileToString() throws Exception {
        mockStatic(Context.class);
        when(Context.enter()).thenReturn(cx);
        FieldUtils.writeField(lessCompiler, "scope", scope, true);
        FieldUtils.writeField(lessCompiler, "compiler", compiler, true);
        FieldUtils.writeField(lessCompiler, "out", out, true);
        when(cx.newObject(scope)).thenReturn(compileScope);

        whenNew(LessSource.class).withArguments(inputFile).thenReturn(lessSource);
        when(lessSource.getNormalizedContent()).thenReturn(less);

        when(out.toString()).thenReturn(css);

        assertEquals(css, lessCompiler.compile(inputFile));

        verify(compiler).call(cx, compileScope, null, new Object[] {});
    }

    @Test
    public void testCompileFileToFile() throws Exception {
        mockStatic(Context.class);
        when(Context.enter()).thenReturn(cx);
        FieldUtils.writeField(lessCompiler, "scope", scope, true);
        FieldUtils.writeField(lessCompiler, "compiler", compiler, true);
        FieldUtils.writeField(lessCompiler, "out", out, true);
        when(cx.newObject(scope)).thenReturn(compileScope);

        whenNew(LessSource.class).withArguments(inputFile).thenReturn(lessSource);
        when(lessSource.getNormalizedContent()).thenReturn(less);

        when(out.toString()).thenReturn(css);

        mockStatic(FileUtils.class);

        lessCompiler.compile(inputFile, outputFile);

        verify(compiler).call(cx, compileScope, null, new Object[] {});

        verifyStatic();
        FileUtils.writeStringToFile(outputFile, css, (String) null);
    }

    @Test
    public void testCompileFileToFileWithForceTrue() throws Exception {
        mockStatic(Context.class);
        when(Context.enter()).thenReturn(cx);
        FieldUtils.writeField(lessCompiler, "scope", scope, true);
        FieldUtils.writeField(lessCompiler, "compiler", compiler, true);
        FieldUtils.writeField(lessCompiler, "out", out, true);
        when(cx.newObject(scope)).thenReturn(compileScope);

        whenNew(LessSource.class).withArguments(inputFile).thenReturn(lessSource);
        when(lessSource.getNormalizedContent()).thenReturn(less);

        when(out.toString()).thenReturn(css);

        mockStatic(FileUtils.class);

        lessCompiler.compile(inputFile, outputFile, true);

        verify(compiler).call(cx, compileScope, null, new Object[] {});

        verifyStatic();
        FileUtils.writeStringToFile(outputFile, css, (String) null);
    }

    @Test
    public void testCompileFileToFileWithForceFalseAndOutputNotExists() throws Exception {
        mockStatic(Context.class);
        when(Context.enter()).thenReturn(cx);
        FieldUtils.writeField(lessCompiler, "scope", scope, true);
        FieldUtils.writeField(lessCompiler, "compiler", compiler, true);
        FieldUtils.writeField(lessCompiler, "out", out, true);
        when(cx.newObject(scope)).thenReturn(compileScope);

        when(outputFile.exists()).thenReturn(false);

        whenNew(LessSource.class).withArguments(inputFile).thenReturn(lessSource);
        when(lessSource.getNormalizedContent()).thenReturn(less);

        when(out.toString()).thenReturn(css);

        mockStatic(FileUtils.class);

        lessCompiler.compile(inputFile, outputFile, false);

        verify(outputFile).exists();

        verify(compiler).call(cx, compileScope, null, new Object[] {});

        verifyStatic();
        FileUtils.writeStringToFile(outputFile, css, (String) null);
    }

    @Test
    public void testCompileFileToFileWithForceFalseAndOutputExistsAndLessSourceModified() throws Exception {
        mockStatic(Context.class);
        when(Context.enter()).thenReturn(cx);
        FieldUtils.writeField(lessCompiler, "scope", scope, true);
        FieldUtils.writeField(lessCompiler, "compiler", compiler, true);
        FieldUtils.writeField(lessCompiler, "out", out, true);
        when(cx.newObject(scope)).thenReturn(compileScope);

        when(outputFile.exists()).thenReturn(true);
        when(outputFile.lastModified()).thenReturn(1l);

        when(inputFile.lastModified()).thenReturn(2l);

        when(out.toString()).thenReturn(css);

        mockStatic(FileUtils.class);

        lessCompiler.compile(inputFile, outputFile, false);

        verify(outputFile).exists();
        verify(outputFile).lastModified();

        verify(compiler).call(cx, compileScope, null, new Object[] {});

        verifyStatic();
        FileUtils.writeStringToFile(outputFile, css, (String) null);
    }

    @Test
    public void testCompileFileToFileWithForceFalseAndOutputExistsAndLessSourceNotModified() throws Exception {
        mockStatic(Context.class);
        when(Context.enter()).thenReturn(cx);
        FieldUtils.writeField(lessCompiler, "scope", scope, true);
        FieldUtils.writeField(lessCompiler, "compiler", compiler, true);
        FieldUtils.writeField(lessCompiler, "out", out, true);
        when(cx.newObject(scope)).thenReturn(compileScope);

        whenNew(LessSource.class).withArguments(inputFile).thenReturn(lessSource);

        when(outputFile.exists()).thenReturn(true);
        when(outputFile.lastModified()).thenReturn(2l);

        when(lessSource.getLastModifiedIncludingImports()).thenReturn(1l);

        lessCompiler.compile(inputFile, outputFile, false);

        verify(outputFile).exists();
        verify(outputFile).lastModified();

    }

    @Test
    public void testCompileLessSourceToString() throws Exception {
        mockStatic(Context.class);
        when(Context.enter()).thenReturn(cx);
        FieldUtils.writeField(lessCompiler, "scope", scope, true);
        FieldUtils.writeField(lessCompiler, "compiler", compiler, true);
        FieldUtils.writeField(lessCompiler, "out", out, true);
        when(cx.newObject(scope)).thenReturn(compileScope);

        when(lessSource.getNormalizedContent()).thenReturn(less);

        when(out.toString()).thenReturn(css);

        assertEquals(css, lessCompiler.compile(lessSource));

        verify(lessSource).getNormalizedContent();

        verify(compiler).call(cx, compileScope, null, new Object[] {});
    }

    @Test
    public void testCompileLessSourceToFile() throws Exception {
        mockStatic(Context.class);
        when(Context.enter()).thenReturn(cx);
        FieldUtils.writeField(lessCompiler, "scope", scope, true);
        FieldUtils.writeField(lessCompiler, "compiler", compiler, true);
        FieldUtils.writeField(lessCompiler, "out", out, true);
        when(cx.newObject(scope)).thenReturn(compileScope);

        when(lessSource.getNormalizedContent()).thenReturn(less);

        when(out.toString()).thenReturn(css);

        mockStatic(FileUtils.class);

        lessCompiler.compile(lessSource, outputFile);

        verify(lessSource).getNormalizedContent();

        verify(compiler).call(cx, compileScope, null, new Object[] {});

        verifyStatic();
        FileUtils.writeStringToFile(outputFile, css, (String) null);
    }

    @Test
    public void testCompileLessSourceToFileWithForceTrue() throws Exception {
        mockStatic(Context.class);
        when(Context.enter()).thenReturn(cx);
        FieldUtils.writeField(lessCompiler, "scope", scope, true);
        FieldUtils.writeField(lessCompiler, "compiler", compiler, true);
        FieldUtils.writeField(lessCompiler, "out", out, true);
        when(cx.newObject(scope)).thenReturn(compileScope);

        when(lessSource.getNormalizedContent()).thenReturn(less);

        when(out.toString()).thenReturn(css);

        mockStatic(FileUtils.class);

        lessCompiler.compile(lessSource, outputFile, true);

        verify(lessSource).getNormalizedContent();

        verify(compiler).call(cx, compileScope, null, new Object[] {});

        verifyStatic();
        FileUtils.writeStringToFile(outputFile, css, (String) null);
    }

    @Test
    public void testCompileLessSourceToFileWithForceFalseAndOutputNotExists() throws Exception {
        mockStatic(Context.class);
        when(Context.enter()).thenReturn(cx);
        FieldUtils.writeField(lessCompiler, "scope", scope, true);
        FieldUtils.writeField(lessCompiler, "compiler", compiler, true);
        FieldUtils.writeField(lessCompiler, "out", out, true);
        when(cx.newObject(scope)).thenReturn(compileScope);

        when(outputFile.exists()).thenReturn(false);

        when(lessSource.getNormalizedContent()).thenReturn(less);

        when(out.toString()).thenReturn(css);

        mockStatic(FileUtils.class);

        lessCompiler.compile(lessSource, outputFile, false);

        verify(outputFile).exists();

        verify(lessSource).getNormalizedContent();

        verify(compiler).call(cx, compileScope, null, new Object[] {});

        verifyStatic();
        FileUtils.writeStringToFile(outputFile, css, (String) null);
    }

    @Test
    public void testCompileLessSourceToFileWithForceFalseAndOutputExistsAndLessSourceModified() throws Exception {
        mockStatic(Context.class);
        when(Context.enter()).thenReturn(cx);
        FieldUtils.writeField(lessCompiler, "scope", scope, true);
        FieldUtils.writeField(lessCompiler, "compiler", compiler, true);
        FieldUtils.writeField(lessCompiler, "out", out, true);
        when(cx.newObject(scope)).thenReturn(compileScope);

        when(outputFile.exists()).thenReturn(true);
        when(outputFile.lastModified()).thenReturn(1l);

        when(lessSource.getLastModifiedIncludingImports()).thenReturn(2l);
        when(lessSource.getNormalizedContent()).thenReturn(less);

        when(out.toString()).thenReturn(css);

        mockStatic(FileUtils.class);

        lessCompiler.compile(lessSource, outputFile, false);

        verify(outputFile).exists();
        verify(outputFile).lastModified();

        verify(lessSource).getLastModifiedIncludingImports();
        verify(lessSource).getNormalizedContent();

        verify(compiler).call(cx, compileScope, null, new Object[] {});

        verifyStatic();
        FileUtils.writeStringToFile(outputFile, css, (String) null);
    }

    @Test
    public void testCompileLessSourceToFileWithForceFalseAndOutputExistsAndLessSourceNotModified()
            throws Exception {
        mockStatic(Context.class);
        when(Context.enter()).thenReturn(cx);
        FieldUtils.writeField(lessCompiler, "scope", scope, true);
        FieldUtils.writeField(lessCompiler, "compiler", compiler, true);
        FieldUtils.writeField(lessCompiler, "out", out, true);
        when(cx.newObject(scope)).thenReturn(compileScope);

        when(outputFile.exists()).thenReturn(true);
        when(outputFile.lastModified()).thenReturn(2l);

        when(lessSource.getLastModifiedIncludingImports()).thenReturn(1l);

        lessCompiler.compile(lessSource, outputFile, false);

        verify(outputFile).exists();
        verify(outputFile).lastModified();

        verify(lessSource).getLastModifiedIncludingImports();
    }

    @Test(expected = LessException.class)
    public void testCompileThrowsLessExceptionWhenCompilationFails() throws Exception {
        mockStatic(Context.class);
        when(Context.enter()).thenReturn(cx);
        FieldUtils.writeField(lessCompiler, "scope", scope, true);
        FieldUtils.writeField(lessCompiler, "compiler", compiler, true);
        FieldUtils.writeField(lessCompiler, "out", out, true);
        when(cx.newObject(scope)).thenReturn(compileScope);

        JavaScriptException javaScriptException = new JavaScriptException(null, null, 0);
        when(compiler.call(cx, compileScope, null, new Object[] {})).thenThrow(javaScriptException);

        assertEquals(css, lessCompiler.compile(less));
    }

    @Test
    public void testCompress() throws Exception {
        mockStatic(Context.class);
        when(Context.enter()).thenReturn(cx);
        lessCompiler.setCompress(true);
        FieldUtils.writeField(lessCompiler, "scope", scope, true);
        FieldUtils.writeField(lessCompiler, "compiler", compiler, true);
        FieldUtils.writeField(lessCompiler, "out", out, true);
        when(cx.newObject(scope)).thenReturn(compileScope);

        when(out.toString()).thenReturn(css);

        assertEquals(css, lessCompiler.compile(less));

        verify(compiler).call(cx, compileScope, null, new Object[] {});
    }

    @Test
    public void testEncoding() throws Exception {
        mockStatic(Context.class);
        when(Context.enter()).thenReturn(cx);
        lessCompiler.setEncoding("utf-8");
        FieldUtils.writeField(lessCompiler, "scope", scope, true);
        FieldUtils.writeField(lessCompiler, "compiler", compiler, true);
        FieldUtils.writeField(lessCompiler, "out", out, true);
        when(cx.newObject(scope)).thenReturn(compileScope);

        whenNew(LessSource.class).withArguments(inputFile).thenReturn(lessSource);
        when(lessSource.getNormalizedContent()).thenReturn(less);

        when(out.toString("utf-8")).thenReturn(css);

        mockStatic(FileUtils.class);

        lessCompiler.compile(inputFile, outputFile);

        verify(compiler).call(cx, compileScope, null, new Object[] {});

        verifyStatic();
        FileUtils.writeStringToFile(outputFile, css, "utf-8");
    }
}