All Downloads are FREE. Search and download functionalities are using the official Maven repository.

uk.co.benjiweber.junitjs.TestClass Maven / Gradle / Ivy

package uk.co.benjiweber.junitjs;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import javax.script.Bindings;
import javax.script.Invocable;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.apache.commons.io.IOUtils;
import org.junit.runner.Description;

public class TestClass {
	private Class suiteClass;
	List testCases;
	private String name;
	private String url;
	private String filename;
	String resolvedName;

    public TestClass(Class suiteClass, String name, List validClassPaths) throws NoSuchMethodException, ScriptException, IOException, URISyntaxException {
    	this.suiteClass = suiteClass;
		this.name = name;
		this.testCases = load(suiteClass);
		this.filename = url.substring(url.lastIndexOf('/')+1);
		for (String path : validClassPaths) {
			if (url.length()>path.length()) {
				String urlStart = url.substring(0, path.length());
				if (urlStart.equals(path)) {
					resolvedName = url.substring(urlStart.length()-1);
					break;
				}
			}
		}
		if (resolvedName==null) {
			System.err.println("unable to find test file in classpath: " + name);
		}
	}
      
    private int findLineNumber(String[] lines, String functionName) {
    	// attempt to find "function functionName" or "functionName = function"
    	Pattern pattern = Pattern.compile(".*((function\\s+" + functionName + ")|(" + functionName + "\\s*=\\s*function)).*",Pattern.DOTALL);
    	for (int lineNumber = 0 ; lineNumber load(Class suiteClass) throws ScriptException, IOException, NoSuchMethodException, URISyntaxException{
		ScriptEngineManager factory = new ScriptEngineManager();
		ScriptEngine engine = factory.getEngineByName("nashorn");
		engine.put("loadResource",new ClassPathLoader(engine));
		loadTestUtilities(engine);
		URL resourceUrl = suiteClass.getResource(name);
		if (resourceUrl==null) throw new FileNotFoundException(name);
		this.url = resourceUrl.toString();
		InputStream s = suiteClass.getResourceAsStream(name);
		if (s==null) throw new FileNotFoundException(name);
		String src = IOUtils.toString(s);
		String[] lines = src.split("\n");
		engine.eval(src);
		List testCases = new ArrayList();
		final Invocable invocable = (Invocable)engine;
		Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
		for (final String key : bindings.keySet()) {
			if (key.matches("^test.*")) {
				testCases.add(new TestCase(TestClass.this,key,findLineNumber(lines,key),new Runnable() {
					@Override
					public void run() {
						try {
							invocable.invokeFunction(key);
						} catch (NoSuchMethodException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (ScriptException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}));
			}
		}
		return testCases;
    }

	public Description createTestDescription() {
		Description desc = Description.createTestDescription(filename,resolvedName);
		for (TestCase test : testCases) {
			desc.addChild(test.createTestDescription());
		}
		return desc;
	}

	private void loadTestUtilities(ScriptEngine engine) throws ScriptException,IOException {
		engine.eval(IOUtils.toString(JSRunner.class.getResource("TestUtils.js")));
	}

	@FunctionalInterface
	public interface Loader {
				
		public void load(String filename) throws ScriptException;
	}
	
	public class ClassPathLoader implements Loader {
		private final ScriptEngine engine;
		public ClassPathLoader(ScriptEngine engine) {
			this.engine = engine;
		}
		@Override
		public void load(String filename) throws ScriptException {
			URL r = suiteClass.getResource(filename);
			String file = r.getFile();
			engine.eval("load(\"" + file.toString() + "\");");
		}
		
	}

}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy