Author: dmorozov
Date: 2008-11-13 14:50:57 -0500 (Thu, 13 Nov 2008)
New Revision: 11154
Added:
trunk/sandbox/ui/queue/src/test/java/org/richfaces/AbstractQueueComponentTest.java
trunk/sandbox/ui/queue/src/test/resources/
trunk/sandbox/ui/queue/src/test/resources/META-INF/
trunk/sandbox/ui/queue/src/test/resources/META-INF/resources-config.xml
trunk/sandbox/ui/queue/src/test/resources/org/
trunk/sandbox/ui/queue/src/test/resources/org/richfaces/
trunk/sandbox/ui/queue/src/test/resources/org/richfaces/root
trunk/sandbox/ui/queue/src/test/resources/org/richfaces/script.xhtml
trunk/sandbox/ui/queue/src/test/resources/org/richfaces/simulation.js
Modified:
trunk/sandbox/ui/queue/src/test/java/org/richfaces/ScriptTest.java
Log:
Queue simulation test implemented in draft
Added: trunk/sandbox/ui/queue/src/test/java/org/richfaces/AbstractQueueComponentTest.java
===================================================================
--- trunk/sandbox/ui/queue/src/test/java/org/richfaces/AbstractQueueComponentTest.java
(rev 0)
+++
trunk/sandbox/ui/queue/src/test/java/org/richfaces/AbstractQueueComponentTest.java 2008-11-13
19:50:57 UTC (rev 11154)
@@ -0,0 +1,369 @@
+/**
+ * License Agreement.
+ *
+ * Rich Faces - Natural Ajax for Java Server Faces (JSF)
+ *
+ * Copyright (C) 2007 Exadel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+package org.richfaces;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIComponentBase;
+import javax.faces.component.UIForm;
+import javax.faces.component.UIViewRoot;
+import javax.faces.component.html.HtmlOutputText;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.faces.render.Renderer;
+
+import org.ajax4jsf.component.UIAjaxCommandButton;
+import org.ajax4jsf.component.UIResource;
+import org.ajax4jsf.component.html.HtmlLoadScript;
+import org.ajax4jsf.javascript.JSFunction;
+import org.ajax4jsf.javascript.JSReference;
+import org.ajax4jsf.renderkit.AjaxRendererUtils;
+import org.ajax4jsf.renderkit.UserResourceRenderer2;
+import org.ajax4jsf.renderkit.RendererUtils.HTML;
+import org.ajax4jsf.tests.AbstractAjax4JsfTestCase;
+import org.mozilla.javascript.NativeArray;
+import org.mozilla.javascript.NativeObject;
+
+import com.gargoylesoftware.htmlunit.AlertHandler;
+import com.gargoylesoftware.htmlunit.Page;
+import com.gargoylesoftware.htmlunit.ScriptResult;
+import com.gargoylesoftware.htmlunit.WebClient;
+import com.gargoylesoftware.htmlunit.html.HtmlPage;
+import com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine;
+import com.sun.facelets.Facelet;
+import com.sun.facelets.FaceletFactory;
+import com.sun.facelets.compiler.SAXCompiler;
+import com.sun.facelets.impl.DefaultFaceletFactory;
+import com.sun.facelets.impl.ResourceResolver;
+
+/**
+ * @author Nick Belaevski
+ * @since 3.3.0
+ */
+public abstract class AbstractQueueComponentTest extends AbstractAjax4JsfTestCase
implements ResourceResolver {
+
+ private static final String COMPONENT_TYPE =
AjaxSubmitFunctionComponent.class.getName();
+
+ public final static class AjaxSubmitFunctionComponent extends UIComponentBase {
+
+ @Override
+ public String getRendererType() {
+ return COMPONENT_TYPE;
+ }
+
+ @Override
+ public String getFamily() {
+ return COMPONENT_TYPE;
+ }
+
+ }
+
+ private final static class AjaxSubmitFunctionResourceRenderer extends
+ Renderer implements UserResourceRenderer2 {
+
+ public void encodeToHead(FacesContext facesContext, UIComponent component)
+ throws IOException {
+ JSFunction ajaxFunction = AjaxRendererUtils.buildAjaxFunction(component,
facesContext);
+ Map<String, Object> options = AjaxRendererUtils.buildEventOptions(facesContext,
component);
+ options.put("requestDelay", new
JSReference("parameters.requestDelay"));
+ options.put("requestId", new JSReference("parameters.requestId ||
'" + component.getClientId(facesContext) + "'"));
+ options.put("data", new JSReference("data"));
+ options.put("requestTime", new JSReference("parameters.requestTime ||
1000"));
+ options.put("timeout", new JSReference("parameters.timeout"));
+ options.put("eventsQueue", new JSReference("parameters.eventsQueue ||
'testQueue'"));
+
+ ajaxFunction.addParameter(options);
+
+ ResponseWriter responseWriter = facesContext.getResponseWriter();
+ responseWriter.startElement(HTML.SCRIPT_ELEM, component);
+ responseWriter.writeAttribute(HTML.TYPE_ATTR, "text/javascript", null);
+ responseWriter.writeText("var ajaxSubmit = function(data, parameters) {" +
ajaxFunction.toScript() + "};", null);
+ responseWriter.endElement(HTML.SCRIPT_ELEM);
+ }
+
+ @Override
+ public void encodeBegin(FacesContext context, UIComponent component)
+ throws IOException {
+ }
+
+ @Override
+ public void encodeEnd(FacesContext context, UIComponent component)
+ throws IOException {
+ ResponseWriter responseWriter = context.getResponseWriter();
+ responseWriter.startElement(HTML.SPAN_ELEM, component);
+ responseWriter.writeAttribute(HTML.id_ATTRIBUTE, component.getClientId(context),
null);
+ responseWriter.writeText("hi", null);
+ responseWriter.endElement(HTML.SPAN_ELEM);
+ }
+ }
+
+ public AbstractQueueComponentTest(String name) {
+ super(name);
+ }
+
+ public URL resolveUrl(String path) {
+ return
Thread.currentThread().getContextClassLoader().getResource("org/richfaces" +
path);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ UIViewRoot viewRoot = facesContext.getViewRoot();
+ UIResource resource;
+
+ UIComponent form = application.createComponent(UIForm.COMPONENT_TYPE);
+ viewRoot.getChildren().add(form);
+ final UIComponent commandButton =
application.createComponent(UIAjaxCommandButton.COMPONENT_TYPE);
+ form.getChildren().add(commandButton);
+
+ facesContext.getRenderKit().addRenderer(COMPONENT_TYPE, COMPONENT_TYPE, new
AjaxSubmitFunctionResourceRenderer());
+ form.getChildren().add(new AjaxSubmitFunctionComponent());
+
+ resource = (UIResource) application.createComponent(HtmlLoadScript.COMPONENT_TYPE);
+ resource.setSrc("resource:///org/richfaces/simulation.js");
+ viewRoot.getChildren().add(resource);
+
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ private List<ScriptCommand> scriptCommands = new
ArrayList<ScriptCommand>();
+
+ private abstract interface ScriptCommand {
+ public void append(StringBuilder builder);
+ }
+
+ private static final class DelayCommand implements ScriptCommand {
+ private int delayValue;
+
+ public DelayCommand(int value) {
+ super();
+ this.delayValue = value;
+ }
+
+ public void append(StringBuilder builder) {
+ builder.append("wait(" + delayValue + ");");
+ }
+ }
+
+ private static final class AjaxCommand implements ScriptCommand {
+ private String data;
+ private String parameters;
+
+ public AjaxCommand(String data, String parameters) {
+ super();
+ this.data = data;
+ this.parameters = parameters;
+ }
+
+ public void append(StringBuilder builder) {
+ builder.append("ajax('" + data + "', " + parameters +
");");
+ }
+ }
+
+ protected static final class TestsResult {
+ private List<RequestData> dataList = new ArrayList<RequestData>();
+
+ private Number currentTime;
+
+ public void addData(RequestData data) {
+ this.dataList.add(data);
+ }
+
+ public List<RequestData> getDataList() {
+ return dataList;
+ }
+
+ public void setCurrentTime(Number number) {
+ this.currentTime = number;
+ }
+
+ public Number getCurrentTime() {
+ return currentTime;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+
+ builder.append("[\n");
+ for (RequestData data : dataList) {
+ builder.append(" ");
+ builder.append(data);
+ builder.append("\n");
+ }
+ builder.append("]\n");
+ builder.append("Current time: " + this.currentTime);
+
+ return builder.toString();
+ }
+ }
+
+ protected static final class RequestData {
+ private boolean timedOut;
+
+ private Number startTime;
+
+ private Number endTime;
+
+ private String data;
+
+ public RequestData(String data, Number startTime, Number endTime,
+ boolean timedOut) {
+ super();
+ this.data = data;
+ this.startTime = startTime;
+ this.endTime = endTime;
+ this.timedOut = timedOut;
+ }
+
+ public boolean isTimedOut() {
+ return timedOut;
+ }
+
+ public Number getStartTime() {
+ return startTime;
+ }
+
+ public Number getEndTime() {
+ return endTime;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+
+ builder.append("data: ");
+ builder.append(data);
+ builder.append(", ");
+
+ builder.append("startTime: ");
+ builder.append(startTime);
+ builder.append(", ");
+
+ builder.append("endTime: ");
+ builder.append(endTime);
+ builder.append(", ");
+
+ if (isTimedOut()) {
+ builder.append("timeout: ");
+ builder.append(true);
+ }
+
+ return builder.toString();
+ }
+ };
+
+ protected void ajax(String data, String parameters) {
+ scriptCommands.add(new AjaxCommand(data, parameters));
+ }
+
+ protected void delay(int delayValue) {
+ scriptCommands.add(new DelayCommand(delayValue));
+ }
+
+ protected void buildView(String viewId) throws IOException {
+ com.sun.facelets.compiler.Compiler c = new SAXCompiler();
+ FaceletFactory factory = new DefaultFaceletFactory(c, this);
+ FaceletFactory.setInstance(factory);
+
+ FaceletFactory f = FaceletFactory.getInstance();
+ Facelet at = f.getFacelet(viewId);
+
+ UIViewRoot root = facesContext.getViewRoot();
+ root.setViewId(viewId);
+ at.apply(facesContext, root);
+ }
+
+ @Override
+ protected HtmlPage renderView() throws Exception {
+ StringBuilder builder = new StringBuilder("<script
type='text/javascript'>do { with (simulationContext) {");
+ for (ScriptCommand command : scriptCommands) {
+ command.append(builder);
+ }
+ builder.append("}; Timer.execute(); } while
(!Timer.isEmpty());</script>");
+
+ HtmlOutputText text = new HtmlOutputText();
+ text.setEscape(false);
+ text.setValue(builder.toString());
+
+ List<UIComponent> childList = facesContext.getViewRoot().getChildren();
+ childList.add(childList.size(), text);
+
+ return super.renderView();
+ }
+
+ protected TestsResult getTestsResult(HtmlPage page) {
+ TestsResult result = new TestsResult();
+
+ ScriptResult scriptResult =
page.executeJavaScript("window.simulationContext.results");
+ NativeArray array = (NativeArray) scriptResult.getJavaScriptResult();
+
+ for (int i = 0; i < array.getLength(); i++) {
+ NativeObject object = (NativeObject) array.get(i, array);
+
+ String data = (String) object.get("data", object);
+ Number startTime = (Number) object.get("startTime", object);
+ Number endTime = (Number) object.get("endTime", object);
+
+ Object timedOut = object.get("timedOut", object);
+ boolean timedOutBoolean = timedOut instanceof Boolean && (Boolean) timedOut;
+
+ result.addData(new RequestData(data, startTime, endTime, timedOutBoolean));
+ }
+
+ scriptResult = page.executeJavaScript("Timer.currentTime");
+ result.setCurrentTime((Number) scriptResult.getJavaScriptResult());
+
+ return result;
+ }
+
+ @Override
+ protected WebClient createWebClient() {
+ WebClient webClient = super.createWebClient();
+ webClient.setJavaScriptEngine(new JavaScriptEngine(webClient));
+ webClient.setAlertHandler(new AlertHandler() {
+
+ public void handleAlert(Page page, String message) {
+ fail(message);
+ }
+
+ });
+
+ return webClient;
+ }
+
+}
Modified: trunk/sandbox/ui/queue/src/test/java/org/richfaces/ScriptTest.java
===================================================================
--- trunk/sandbox/ui/queue/src/test/java/org/richfaces/ScriptTest.java 2008-11-13 19:49:04
UTC (rev 11153)
+++ trunk/sandbox/ui/queue/src/test/java/org/richfaces/ScriptTest.java 2008-11-13 19:50:57
UTC (rev 11154)
@@ -22,68 +22,30 @@
package org.richfaces;
-import java.util.List;
-
-import javax.faces.component.UIComponent;
-import javax.faces.component.UIForm;
-
-import org.ajax4jsf.component.UIAjaxFunction;
-import org.ajax4jsf.tests.AbstractAjax4JsfTestCase;
-import org.richfaces.component.UIQueue;
-
-import com.gargoylesoftware.htmlunit.ScriptResult;
-import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
-import com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine;
/**
* @author mikalaj
*
*/
-public class ScriptTest extends AbstractAjax4JsfTestCase {
+public class ScriptTest extends AbstractQueueComponentTest {
public ScriptTest(String name) {
super(name);
}
- @Override
- protected WebClient createWebClient() {
- WebClient webClient = super.createWebClient();
- webClient.setJavaScriptEngine(new JavaScriptEngine(webClient));
+ public void testScript() throws Exception {
+ buildView("/script.xhtml");
- return webClient;
- }
-
- @Override
- public void setUp() throws Exception {
- super.setUp();
+ delay(500);
+ ajax("a", "{requestDelay: 1000, requestId: '12', requestTime:
1500}");
+ delay(4100);
+ ajax("b", "{requestDelay: 4100, requestId: '12', requestTime:
101, timeout: 10}");
- List<UIComponent> viewRootChildren = facesContext.getViewRoot().getChildren();
-
- viewRootChildren.add(application.createComponent(UIQueue.COMPONENT_TYPE));
-
- UIComponent form = application.createComponent(UIForm.COMPONENT_TYPE);
- viewRootChildren.add(form);
- UIAjaxFunction function = (UIAjaxFunction)
application.createComponent(UIAjaxFunction.COMPONENT_TYPE);
- function.setName("ajaxSubmit");
- form.getChildren().add(function);
-
- }
-
- @Override
- public void tearDown() throws Exception {
- super.tearDown();
- }
-
- public void testScript() throws Exception {
HtmlPage page = this.renderView();
assertNotNull(page);
- ScriptResult scriptResult =
page.executeJavaScript("setTimeout(function(){A4J.AJAX.EventQueue.getOrCreateQueue('"
+
- UIQueue.GLOBAL_QUEUE_NAME + "')}, 2000000)");
- System.out.println(scriptResult.getJavaScriptResult());
-
-
+ System.out.println(getTestsResult(page));
}
}
Added: trunk/sandbox/ui/queue/src/test/resources/META-INF/resources-config.xml
===================================================================
--- trunk/sandbox/ui/queue/src/test/resources/META-INF/resources-config.xml
(rev 0)
+++ trunk/sandbox/ui/queue/src/test/resources/META-INF/resources-config.xml 2008-11-13
19:50:57 UTC (rev 11154)
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resource-config>
+
+ <resource>
+ <name>org/richfaces/simulation.js</name>
+ <path>org/richfaces/simulation.js</path>
+ </resource>
+
+ <resource>
+ <name>org.richfaces.AbstractQueueComponentTest</name>
+ <path>org.richfaces.AbstractQueueComponentTest</path>
+ </resource>
+
+</resource-config>
Added: trunk/sandbox/ui/queue/src/test/resources/org/richfaces/root
===================================================================
Added: trunk/sandbox/ui/queue/src/test/resources/org/richfaces/script.xhtml
===================================================================
--- trunk/sandbox/ui/queue/src/test/resources/org/richfaces/script.xhtml
(rev 0)
+++ trunk/sandbox/ui/queue/src/test/resources/org/richfaces/script.xhtml 2008-11-13
19:50:57 UTC (rev 11154)
@@ -0,0 +1,19 @@
+<html
+
xmlns:h="http://java.sun.com/jsf/html"
+
xmlns:f="http://java.sun.com/jsf/core"
+
xmlns:ui="http://java.sun.com/jsf/facelets"
+
xmlns:a4j="http://richfaces.org/a4j"
+
xmlns:c="http://java.sun.com/jstl/core"
+
xmlns:q="http://labs.jboss.com/jbossrichfaces/ui/ui/queue">
+ <head>
+ <title></title>
+ </head>
+ <body>
+ <f:view>
+ <a4j:status startText="...running..." stopText="stopped"
startStyle="color: green" />
+
+ <q:queue size="2" sizeExceededBehavior="fireNext"
name="testQueue" />
+
+ </f:view>
+ </body>
+</html>
Added: trunk/sandbox/ui/queue/src/test/resources/org/richfaces/simulation.js
===================================================================
--- trunk/sandbox/ui/queue/src/test/resources/org/richfaces/simulation.js
(rev 0)
+++ trunk/sandbox/ui/queue/src/test/resources/org/richfaces/simulation.js 2008-11-13
19:50:57 UTC (rev 11154)
@@ -0,0 +1,120 @@
+var Timer = {
+
+ _eventCounter: 0,
+
+ currentTime: 0,
+
+ maxTime: 100000,
+
+ events: new Array(),
+
+ addEventToTimer: function(callback, delay) {
+ var eventTime = this.currentTime + delay;
+
+ var i = 0;
+
+ while (this.events[i] && (this.events[i].eventTime <= eventTime)) {
+ i++;
+ }
+
+ var eventId = this._eventCounter++;
+
+ this.events.splice(i, 0, {eventTime: eventTime, callback: callback, eventId:
eventId});
+
+ return eventId;
+ },
+
+ removeEventFromTimer: function(eventId) {
+ for ( var i = 0; i < this.events.length; i++) {
+ if (this.events[i].eventId == eventId) {
+ this.events.splice(i, 1);
+
+ break;
+ }
+ }
+ },
+
+ execute: function() {
+ while (this.events.length > 0) {
+ var eventData = this.events.shift();
+
+ this.currentTime = eventData.eventTime;
+ if (this.currentTime > this.maxTime) {
+ throw "Maximum execution time reached, aborting timer";
+ }
+
+ try {
+
+ eventData.callback();
+ } catch (e) {
+ alert(e.message);
+ }
+ }
+ },
+
+ isEmpty: function() {
+ return this.events.length == 0;
+ }
+};
+
+window.setTimeout = function(callback, delay) {
+ return Timer.addEventToTimer(callback, delay);
+}
+
+window.clearTimeout = function(timerId) {
+ Timer.removeEventFromTimer(timerId);
+}
+
+window.simulationContext = {
+
+ results: new Array(),
+
+ delay: 0,
+
+ wait: function(delay) {
+ this.delay += delay;
+ },
+
+ ajax: function() {
+ var args = arguments;
+ ajaxSubmit(args[0], args[1]);
+
+ Timer.addEventToTimer(function() {
+ ajaxSubmit(args[0], args[1]);
+ }, this.delay);
+ }
+ };
+
+A4J.AJAX.SubmitQuery = function(query, options) {
+ var request = {};
+
+ var length = window.simulationContext.results.push({data: options.data, startTime:
Timer.currentTime});
+
+ var timer = Timer.addEventToTimer(function() {
+ if (request.timeoutTimer) {
+ Timer.removeEventFromTimer(request.timeoutTimer);
+ }
+
+ if (request.queue) {
+ request.queue.pop();
+ }
+
+ window.simulationContext.results[length - 1].endTime = Timer.currentTime;
+
+ }, options.requestTime);
+
+ if (options.timeout) {
+ request.timeoutTimer = Timer.addEventToTimer(function() {
+ Timer.removeEventFromTimer(timer);
+ if (request.queue) {
+ request.queue.pop();
+ }
+
+ window.simulationContext.results[length - 1].timedOut = true;
+ window.simulationContext.results[length - 1].endTime = Timer.currentTime;
+ }, options.timeout);
+ }
+
+ return request;
+}
+