Package com.philmander.jstest

Source Code of com.philmander.jstest.PhantomTestRunner

package com.philmander.jstest;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.SystemUtils;

import com.google.common.io.Files;
import com.philmander.jstest.JsTestResult.ResultType;

/**
* Standalone class for running js unit tests with Phantom
* @author Phil Mander
*
*/
public class PhantomTestRunner {

  private  JsTestLogger logger = null;

  private static final String PHANTOM_QUNIT_RUNNER = "qunit-phantom-runner.js";
 
  private static final String PASS_PREFIX = "Test passed";
 
  private static final String FAIL_PREFIX = "Test failed";
 
  private static final String ERROR_PREFIX = "Test error";

  private String phantom = null;

  /**
   * CLI for phantom test runner
   * @param args
   */
  public static void main(String[] args) {   
   
    File currentDir = new File(".");
   
    CommandLineParser parser = new PosixParser();

    // create the Options
    Options options = new Options();
    options.addOption( "p", "phantom", true, "Location of Phantom JS executable" );
   
    try {     
     
      JsTestLogger logger = new JsTestLogger() {
       
        public void log(String msg) {
          System.out.println("[jstest] " + msg);         
        }
       
        public void error(String msg) {
          System.err.println("[jstest] " + msg);
        }
      };
     
      CommandLine cl = parser.parse(options, args);
     
      String phantomOption = cl.getOptionValue('p');
      File phantomLoc = new File(currentDir, phantomOption);
     
      PhantomTestRunner testRunner = new PhantomTestRunner(phantomLoc.getAbsolutePath());
      testRunner.setLogger(logger);
     
      List<String> testFiles = new ArrayList<String>();
      for(Object arg : cl.getArgList()) {
       
        File testFile = new File(currentDir, (String)arg);
        if(testFile.exists()) {
          testFiles.add(testFile.getAbsolutePath());
        } else {
          logger.error("Couldn't find " + testFile.getAbsolutePath());
        }
      }
     
      logger.log("Using Phantom JS at : " + phantomLoc.getAbsolutePath());
      logger.log("Running tests on " + testFiles.size() + " files");
     
      testRunner.runTests(testFiles.toArray(new String[testFiles.size()]));
                 
    } catch (ParseException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (FileNotFoundException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
 
  /**
   * @param phantom The location of the phantom executable
   * @throws FileNotFoundException
   */
  public PhantomTestRunner(String phantom) throws FileNotFoundException {
   
    File phantomFile = new File(phantom);
    if(!phantomFile.exists()) {       
      throw new FileNotFoundException("Phantom executable does not exist for " + SystemUtils.OS_NAME + "(" + phantom + ")");
    }
   
    this.phantom = phantom;
  }
 
  public JsTestResults runTests(String[] testFiles) throws IOException {   
       
    JsTestResults results = new JsTestResults();
       
    //set up process params
    String qunitRunner = setupPhantomRunnerFile();
   
    for (String testFile : testFiles) {
     
      String loc = fixFilePath(testFile);
      String[] params = {
          phantom, qunitRunner, loc
      };
     
      //set up process
      ProcessBuilder processBuilder = new ProcessBuilder(params);
      Process process = processBuilder.start();
     
      //read and parse output from phantom
      BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
     
      StringBuilder message = new StringBuilder();
      String line = null;
            boolean keepProcessing = true;
            while (keepProcessing) {
                 line = input.readLine();
                 if (line != null && line.equalsIgnoreCase("EOF")) {
                     keepProcessing = false;
                 } else {
                     keepProcessing = true;
                 }
        //TODO: totally need to refactor reporting parsing
        if(logger != null) {
          logger.log(line);
        }
             
        message.append(line + "\n");
       
        if(line.startsWith(PASS_PREFIX) || line.startsWith(FAIL_PREFIX) || line.startsWith(ERROR_PREFIX)) {
                 
          ResultType result;
          if(line.startsWith(PASS_PREFIX)) {
            result = ResultType.PASS;           
          } else if(line.startsWith(FAIL_PREFIX)) {           
            result = ResultType.FAIL;         
          } else {
            result = ResultType.ERROR;
          }
         
          JsTestResult testResult = new JsTestResult(result, message.toString());
          results.addResult(testResult);
         
          //reset message
          message.setLength(0);
        }
      }
     
      process.destroy();
    }
       
    return results;
  }
 
  /**
   * Returns a standard summary message on test failure
   * @param failCount
   * @param errorCount
   * @return
   */
  public static String getFailureMessage(int failCount, int errorCount) {
    String pluralFail = failCount > 1 ? "s" : "";
    String pluralErrors = errorCount > 1 ? "s" : "";
    String message = "JS tests failed. " + failCount + " test" + pluralFail + " failed. " + errorCount + " error" + pluralErrors + ".";
    return message;
  }

  /**
   * Returns a standard summary message on test success
   * @param passCount
   * @return
   */
  public static String getSuccessMessage(int passCount) {
    String pluralPass = passCount > 1 ? "s" : "";
    String message = "JS tests passed. " + passCount + " test" + pluralPass + " passed.";
    return message;
  }
 
  private String setupPhantomRunnerFile()  throws IOException {
   
    File tempDir = Files.createTempDir();
    File tempLoc = new File(tempDir, PHANTOM_QUNIT_RUNNER);   
    FileUtils.copyInputStreamToFile(
        this.getClass().getClassLoader().getResourceAsStream(PHANTOM_QUNIT_RUNNER),
        tempLoc);
       
    return tempLoc.getAbsolutePath();
  }
 
  private static String fixFilePath(String loc) {
    File file = new File(loc);
    String path = "file:///" + file.getAbsolutePath().replace("\\", "/");
    return path;
  }

  /**
   * Sets a logger for the test runner to report results to.  Use before calling runTests()
   * @param logger
   */
  public void setLogger(JsTestLogger logger) {
    this.logger = logger;
  }
}
TOP

Related Classes of com.philmander.jstest.PhantomTestRunner

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.