package com.eas.application; import com.eas.client.scripts.ScriptedResource; import com.eas.script.Scripts; import com.eas.script.SystemJSCallback; import java.util.concurrent.atomic.AtomicReference; import java.util.logging.Level; import java.util.logging.Logger; import jdk.nashorn.api.scripting.AbstractJSObject; import jdk.nashorn.api.scripting.JSObject; import static org.junit.Assert.fail; /** * * @author mg */ public class ScriptedTests { protected void start(String aTestModuleName, long aTimeout) throws InterruptedException { Object success = new Object(); Object failure = new Object(); long started = System.currentTimeMillis(); AtomicReference<Object> completion = new AtomicReference(); withFacade(completion, () -> { try { ScriptedResource.require(new String[]{aTestModuleName}, null, new AbstractJSObject() { @Override public Object call(final Object thiz, final Object... args) { JSObject testModule = Scripts.getSpace().lookup(aTestModuleName); JSObject testInstance = (JSObject) testModule.newObject(); JSObject execute = (JSObject) testInstance.getMember("execute"); try { execute.call(testInstance, new Object[]{new SystemJSCallback() { @Override public Object call(final Object thiz, final Object... args) { completion.set(success); return null; } }, new SystemJSCallback() { @Override public Object call(final Object thiz, final Object... args) { completion.set(args.length > 0 ? args[0] : failure); return null; } }}); } catch (Throwable t) { completion.set(t); } return null; } }, new AbstractJSObject() { @Override public Object call(final Object thiz, final Object... args) { completion.set(args[0]); return null; } }); } catch (Exception ex) { Logger.getLogger(ScriptedTests.class.getName()).log(Level.SEVERE, null, ex); completion.set(ex); } }); while (completion.get() == null && System.currentTimeMillis() < started + aTimeout) { Thread.sleep(10); } Object lastChance = completion.get(); if (lastChance != success) { String failedText = aTestModuleName + " failed due to: "; if (lastChance == null) { fail(failedText + "timeout"); } else if (lastChance == failure) { fail(failedText + "unknown problem"); } else if (lastChance instanceof Throwable) { fail(failedText + lastChance.toString()); } else if (lastChance instanceof JSObject) { String jsonView = Scripts.getSpace().toJson(lastChance); fail(failedText + (jsonView.length() > 2 ? jsonView : lastChance.toString())); } else { fail(failedText + lastChance.toString()); } } else { Logger.getLogger(ScriptedTests.class.getName()).log(Level.INFO, "{0} completed", aTestModuleName); } } private void withFacade(AtomicReference<Object> aCompletion, Runnable withFacade) { Scripts.getSpace().process(() -> { try { if (Scripts.getSpace().getDefined().containsKey("facade")) { withFacade.run(); } else { ScriptedResource.require(new String[]{"facade"}, null, new AbstractJSObject() { @Override public Object call(final Object thiz, final Object... args) { JSObject facade = Scripts.getSpace().lookup("facade"); JSObject cacheBust = (JSObject) facade.getMember("cacheBust"); cacheBust.call(facade, new Object[]{true}); JSObject export = (JSObject) facade.getMember("export"); export.call(facade, new Object[]{Scripts.getSpace().getGlobal()}); withFacade.run(); return null; } }, new AbstractJSObject() { @Override public Object call(final Object thiz, final Object... args) { aCompletion.set(args[0]); return null; } }); } } catch (Exception ex) { aCompletion.set(ex); } }); } }