JavaScript Compiles Unit Test

This isn’t rocket science, but it made me happy.

With the help of Rhino JavaScript and the Rhino Shell, the following unit test makes sure that your project’s JavaScript compiles, so you don’t have to build, deploy, and launch the app just to discover that there are syntax errors.

package ca.intelliware.project.foo;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.commons.io.DirectoryWalker;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.jmock.cglib.MockObjectTestCase;

public class JavaScriptTest extends MockObjectTestCase {

  private static final String JAVASCRIPT_DIRECTORY = "./src/main/webapp/js";

  public void testJavaScriptCompiles()
    throws Exception {
    File javaScriptDirectory = new File(JAVASCRIPT_DIRECTORY);
    List<File> files = new JavaScriptFinder().findAllJavaScript(javaScriptDirectory);
    for (File file : files) {
      File tempFile = writeJavaScriptErrors(file.getAbsolutePath());
      List<String> lines = readJavaScriptErrors(tempFile);
      String errors = StringUtils.join(lines, "\n");
      assertTrue("javascript errors: " + errors, lines.isEmpty());
    }
  }

  private File writeJavaScriptErrors(String javaScriptFileName)
    throws IOException, FileNotFoundException {
    PrintStream systemErr = System.err;
    File tempFile = File.createTempFile("test", ".txt");
    PrintStream out = new PrintStream(tempFile);
    System.setErr(out);
    org.mozilla.javascript.tools.shell.Main.exec(new String[] {javaScriptFileName});
    out.close();
    System.setErr(systemErr);
    return tempFile;
  }

  private List<String> readJavaScriptErrors(File tempFile)
    throws FileNotFoundException, IOException {
    BufferedReader in = new BufferedReader(new FileReader(tempFile));
    String line;
    List<String> lines = new ArrayList<String>();
    while ((line = in.readLine()) != null) {
      lines.add(line);
    }
    in.close();
    return lines;
  }

  public class JavaScriptFinder extends DirectoryWalker {

    @SuppressWarnings("unchecked")
    @Override
    protected void handleFile(File file, int depth, Collection results)
      throws IOException {
      if ("js".equals(FilenameUtils.getExtension(file.getName())))           {
        results.add(file);
      }
    }

    public List<File> findAllJavaScript(File startDirectory)
      throws IOException {
      List<File> results = new ArrayList<File>();
      walk(startDirectory, results);
      return results;
    }
  }
}

It's only fair to share...
Share on FacebookGoogle+Tweet about this on TwitterShare on LinkedIn

Leave a Reply