From: Manuel Carrasco MoƱino Date: Mon, 4 Mar 2013 13:16:50 +0000 (+0100) Subject: Implementation of Deferred.when. Some changes and deprecations in Function (need... X-Git-Tag: release-1.4.0~75 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=02a7de8983334dcec152c35a6f20cda60f374b39;p=gwtquery.git Implementation of Deferred.when. Some changes and deprecations in Function (need discussion). All Ajax methods now returns a Deferred --- diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/Function.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/Function.java index 5bb4f5f6..76a0bc3c 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/Function.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/Function.java @@ -52,6 +52,9 @@ public abstract class Function { index = i; } + /** + * @deprecated use getArguments instead. + */ @Deprecated public Object[] getData() { return getArguments(); @@ -61,6 +64,9 @@ public abstract class Function { return arguments; } + /** + * @deprecated use use setArguments instead + */ @Deprecated public void setData(Object...arguments) { setArguments(arguments); @@ -75,7 +81,9 @@ public abstract class Function { /** * Return the first element of the arguments list + * @deprecated use getArgument(idx) instead. */ + @Deprecated public Object getDataObject() { return getArgument(0); } @@ -89,10 +97,50 @@ public abstract class Function { } /** - * return the argument in position idx; + * Utility method for safety getting a JavaScriptObject present at a certain + * position in the list of arguments composed by arrays. + * + */ + public T getArgumentJSO(int argIdx, int pos) { + Object[] objs = getArgumentArray(argIdx); + if (objs.length > pos && objs[pos] instanceof JavaScriptObject) { + return ((JavaScriptObject)objs[pos]).cast(); + } + return null; + } + + /** + * Utility method for safety getting a JavaScriptObject present at a certain + * position in the list of arguments. + */ + public T getArgumentJSO(int idx) { + return getArgumentJSO(-1, idx); + } + + /** + * Utility method for safety getting an array present at a certain + * position in the list of arguments. + * + * Useful for Deferred chains where result of each resolved + * promise is set as an array in the arguments list. + * + * Always returns an array. + */ + public Object[] getArgumentArray(int idx) { + Object o = idx < 0 ? arguments: getArgument(idx); + if (o != null && o.getClass().isArray()) { + return (Object[])o; + } else if (idx == 0) { + return arguments; + } + return new Object[0]; + } + + /** + * return the argument in the position idx; */ public Object getArgument(int idx) { - return arguments != null && arguments.length > idx ? arguments[idx] : null; + return arguments.length > idx ? arguments[idx] : null; } public Properties getDataProperties() { @@ -100,11 +148,7 @@ public abstract class Function { } public Properties getDataProperties(int idx) { - Object o = getArgument(idx); - if (o != null && o instanceof JavaScriptObject) { - return (Properties)o; - } - return null; + return getArgumentJSO(idx); } public void setData(boolean b) { @@ -115,8 +159,8 @@ public abstract class Function { setData(Double.valueOf(b)); } - public void setDataObject(Object data) { - setArguments(data); + public void setDataObject(Object arg) { + setArguments(arg); } public int getIndex() { @@ -204,8 +248,8 @@ public abstract class Function { /** * Override this method for bound callbacks */ - public Object f(Object... data) { - setArguments(data); + public Object f(Object... args) { + setArguments(args); f(); return true; } @@ -213,22 +257,22 @@ public abstract class Function { /** * Override this method for bound callbacks */ - public void f(int i, Object data) { - f(i, new Object[]{data}); + public void f(int i, Object arg) { + f(i, new Object[]{arg}); } /** * Override this method for bound callbacks */ - public void f(int i, Object... data) { + public void f(int i, Object... args) { setIndex(i); - setArguments(data); - if (data.length == 1 && data[0] instanceof JavaScriptObject) { - if (JsUtils.isElement((JavaScriptObject)data[0])) { - setElement((com.google.gwt.dom.client.Element)data[0]); + setArguments(args); + if (args.length == 1 && args[0] instanceof JavaScriptObject) { + if (JsUtils.isElement((JavaScriptObject)args[0])) { + setElement((com.google.gwt.dom.client.Element)args[0]); f(getElement(), i); - } else if (JsUtils.isEvent((JavaScriptObject)data[0])) { - setEvent((Event)data[0]); + } else if (JsUtils.isEvent((JavaScriptObject)args[0])) { + setEvent((Event)args[0]); f(getEvent()); } else { f(); @@ -240,8 +284,8 @@ public abstract class Function { * Override this method for bound event handlers if you wish to deal with * per-handler user data. */ - public boolean f(Event e, Object data) { - setArguments(data); + public boolean f(Event e, Object arg) { + setArguments(arg); setEvent(e); return f(e); } @@ -319,8 +363,8 @@ public abstract class Function { * catch the exception and send it to the GWT UncaughtExceptionHandler * They are intentionally final to avoid override them */ - public final void fe(Object data) { - fe(new Object[]{data}); + public final void fe(Object arg) { + fe(new Object[]{arg}); } /** @@ -328,16 +372,16 @@ public abstract class Function { * catch the exception and send it to the GWT UncaughtExceptionHandler * They are intentionally final to avoid override them */ - public final Object fe(Object... data) { + public final Object fe(Object... args) { if (GWT.getUncaughtExceptionHandler() != null) { try { - return f(data); + return f(args); } catch (Exception e) { GWT.getUncaughtExceptionHandler().onUncaughtException(e); } return true; } - return f(data); + return f(args); } /** @@ -345,16 +389,16 @@ public abstract class Function { * catch the exception and send it to the GWT UncaughtExceptionHandler * They are intentionally final to avoid override them */ - public final boolean fe(Event ev, Object data) { + public final boolean fe(Event ev, Object arg) { if (GWT.getUncaughtExceptionHandler() != null) { try { - return f(ev, data); + return f(ev, arg); } catch (Exception e) { GWT.getUncaughtExceptionHandler().onUncaughtException(e); } return true; } - return f(ev, data); + return f(ev, arg); } /** diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java index 1a2afc78..e2332181 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java @@ -51,6 +51,7 @@ import com.google.gwt.query.client.js.JsNodeArray; import com.google.gwt.query.client.js.JsObjectArray; import com.google.gwt.query.client.js.JsRegexp; import com.google.gwt.query.client.js.JsUtils; +import com.google.gwt.query.client.plugins.Deferred; import com.google.gwt.query.client.plugins.Effects; import com.google.gwt.query.client.plugins.Events; import com.google.gwt.query.client.plugins.Plugin; @@ -540,8 +541,8 @@ public class GQuery implements Lazy { /** * Perform an ajax request to the server using GET. */ - public static void get(String url, Properties data, final Function onSuccess) { - Ajax.get(url, data, onSuccess); + public static Promise get(String url, Properties data, final Function onSuccess) { + return Ajax.get(url, data, onSuccess); } /** @@ -584,8 +585,8 @@ public class GQuery implements Lazy { /** * Perform an ajax request to the server using POST and parsing the json response. */ - public static void getJSON(String url, Properties data, final Function onSuccess) { - Ajax.getJSON(url, data, onSuccess); + public static Promise getJSON(String url, Properties data, final Function onSuccess) { + return Ajax.getJSON(url, data, onSuccess); } /** @@ -610,8 +611,8 @@ public class GQuery implements Lazy { * */ - public static void getJSONP(String url, Properties data, final Function onSuccess) { - Ajax.getJSONP(url, data, onSuccess); + public static Promise getJSONP(String url, Properties data, final Function onSuccess) { + return Ajax.getJSONP(url, data, onSuccess); } protected static DocumentStyleImpl getStyleImpl() { @@ -694,8 +695,8 @@ public class GQuery implements Lazy { /** * Perform an ajax request to the server using POST. */ - public static void post(String url, Properties data, final Function onSuccess) { - Ajax.post(url, data, onSuccess); + public static Promise post(String url, Properties data, final Function onSuccess) { + return Ajax.post(url, data, onSuccess); } public static Class registerPlugin(Class plugin, Plugin pluginFactory) { @@ -706,6 +707,19 @@ public class GQuery implements Lazy { plugins.put(plugin, pluginFactory); return plugin; } + + /** + * Provides a way to execute callback Functions based on one or more Promise objects + * that represent asynchronous events. + * + * Returns a new promise which will be finalized when all of its subordinates finish. + * In the case of all subordinates are resolved correctly the promise will be resolved + * otherwise it will be rejected. + * + */ + public static Promise when(Promise... subordinates) { + return Deferred.when(subordinates); + } private static native void scrollIntoViewImpl(Node n) /*-{ if (n) @@ -744,9 +758,12 @@ public class GQuery implements Lazy { } protected GQuery(GQuery gq) { - this(gq == null ? null : gq.get()); - currentSelector = gq.getSelector(); - currentContext = gq.getContext(); + if (gq != null) { + elements = gq.elements; + nodeList = gq.nodeList; + currentSelector = gq.currentSelector; + currentContext = gq.currentContext; + } } private GQuery(JsNodeArray nodes) { @@ -4546,7 +4563,7 @@ public class GQuery implements Lazy { public boolean visible() { return isVisible(); } - + /** * Return the first non null attached widget from the matched elements or null if there isn't any. */ diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/Promise.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/Promise.java index c31e0c99..bb7b24cc 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/Promise.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/Promise.java @@ -24,18 +24,50 @@ public interface Promise { public static final String REJECTED = "rejected"; public static final String RESOLVED = "resolved"; + /** + * Add handlers to be called when the Deferred object is either resolved or rejected. + */ Promise always(Function... o); + /** + * Add handlers to be called when the Deferred object is resolved. + */ Promise done(Function... o); + /** + * Add handlers to be called when the Deferred object is rejected. + */ Promise fail(Function... o); + /** + * Utility method to filter and/or chain Deferreds. + * + * @deprecated use 'then' instead. + * it was deprecated in jquery, and we maintain it here for compatibility. + */ + @Deprecated Promise pipe(Function... f); + /** + * Utility method to filter and/or chain Deferreds. + */ Promise progress(Function... o); + /** + * Return the status of the deferred object. + * + * Valid values are: Promise.PENDING, Promise.REJECTED, Promise.RESOLVED + * + */ String state(); + /** + * Add handlers to be called when the Deferred object is resolved, rejected, or still in progress. + * + * @param f a list of 1, 2, or 3 functions, which will be used in this way: + * 1st function will be called when the deferred is resolved. + * 2nd function that is called when the deferred is rejected. + * 3rd one will be called when progress notifications are sent. + */ Promise then(Function... f); - } \ No newline at end of file diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Deferred.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Deferred.java index 6b89b884..24d977c6 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Deferred.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Deferred.java @@ -13,6 +13,10 @@ */ package com.google.gwt.query.client.plugins; +import static com.google.gwt.query.client.Promise.PENDING; +import static com.google.gwt.query.client.Promise.REJECTED; +import static com.google.gwt.query.client.Promise.RESOLVED; + import com.google.gwt.query.client.Function; import com.google.gwt.query.client.GQuery; import com.google.gwt.query.client.Promise; @@ -23,6 +27,9 @@ import com.google.gwt.query.client.plugins.callbacks.Callbacks; */ public class Deferred extends GQuery { + /** + * Implementation of the Promise interface which is used internally by Deferred. + */ private class DeferredPromise extends GQuery implements Promise { private Deferred dfd; @@ -37,17 +44,17 @@ public class Deferred extends GQuery { } } - public Promise always(Function... o) { - return done(o).fail(o); + public Promise always(Function... f) { + return done(f).fail(f); } - public Promise done(Function... o) { - dfd.resolve.add(o); + public Promise done(Function... f) { + dfd.resolve.add(f); return this; } - public Promise fail(Function... o) { - dfd.reject.add(o); + public Promise fail(Function... f) { + dfd.reject.add(f); return this; } @@ -55,8 +62,8 @@ public class Deferred extends GQuery { return then(f); } - public Promise progress(Function... o) { - dfd.notify.add(o); + public Promise progress(Function... f) { + dfd.notify.add(f); return this; } @@ -65,23 +72,87 @@ public class Deferred extends GQuery { } public Promise then(Function... f) { + assert f.length < 4 : "Promise.then: Too much arguments"; switch (f.length) { - case 3: progress(f[0]); - case 2: fail(f[0]); + case 3: progress(f[2]); + case 2: fail(f[1]); case 1: done(f[0]); } return this; } } + + /** + * Internal Deferred class used to combine a set of subordinate promises. + */ + private static class WhenDeferred extends Deferred { + /** + * Internal function used to track whether all deferred + * subordinates are resolved. + */ + private class DoneFnc extends Function { + final int idx; + public DoneFnc(int i, Deferred d) { + idx = i; + } + public Object f(Object... args) { + values[idx] = args; + if (--remaining == 0) { + WhenDeferred.this.resolve(values); + } + return true; + } + } + + private Function failFnc = new Function() { + public Object f(Object... o) { + WhenDeferred.this.reject(o); + return true; + } + }; + + private Function progressFnc = new Function() { + public Object f(Object... o) { + WhenDeferred.this.notify(o); + return true; + } + }; + + // Remaining counter + private int remaining; + + // An indexed array with the fired values of all subordinated + private final Object[] values; + + public WhenDeferred(Promise[] sub) { + int l = remaining = sub.length; + values = new Object[l]; + for (int i = 0; i < l; i++) { + sub[i].done(new DoneFnc(i, this)).progress(progressFnc).fail(failFnc); + } + } + } + + // Register Deferred as a GQuery plugin public static final Class Deferred = GQuery.registerPlugin( Deferred.class, new Plugin() { public Deferred init(GQuery gq) { return new Deferred(gq); } }); - public static Promise when(Deferred d) { - return d.promise(); + + public static Promise when(Promise... d) { + final int n = d.length; + switch (n) { + case 1: + return d[0]; + case 0: + return new Deferred().resolve().promise(); + default: + return new WhenDeferred(d).promise(); + } } + private Callbacks notify = new Callbacks("memory"); private Promise promise = null; @@ -90,13 +161,17 @@ public class Deferred extends GQuery { private Callbacks resolve = new Callbacks("once memory"); - private String state = Promise.PENDING; + private String state = PENDING; + + public Deferred() { + this(null); + } protected Deferred(GQuery gq) { super(gq); resolve.add(new Function() { public void f() { - state = Promise.RESOLVED; + state = RESOLVED; resolve.disable(); notify.lock(); } @@ -104,35 +179,25 @@ public class Deferred extends GQuery { reject.add(new Function() { public void f() { - state = Promise.REJECTED; + state = REJECTED; reject.disable(); notify.lock(); } }); } - // private, used from jsni - @SuppressWarnings("unused") - private void err(Object o) { - reject(o); - } + public Deferred notify(Object... o) { + notify(o); notify.fire(o); return this; } - - // private, used from jsni - @SuppressWarnings("unused") - private void ok(Object o) { - resolve(o); - } - + public Promise promise() { if (promise == null) { promise = new DeferredPromise(this); } return promise; } - public Deferred reject(Object... o) { reject.fire(o); @@ -143,4 +208,16 @@ public class Deferred extends GQuery { resolve.fire(o); return this; } + + // private, used from jsni because it does not handles variable arguments + @SuppressWarnings("unused") + private void err(Object o) { + reject(o); + } + + // private, used from jsni because it does not handles variable arguments + @SuppressWarnings("unused") + private void ok(Object o) { + resolve(o); + } } diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/ajax/Ajax.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/ajax/Ajax.java index 0c60de9c..08f7a1a3 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/ajax/Ajax.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/ajax/Ajax.java @@ -36,7 +36,7 @@ import com.google.gwt.xhr.client.XMLHttpRequest; * */ public class Ajax extends GQuery { - + /** * Ajax Settings object */ @@ -108,16 +108,19 @@ public class Ajax extends GQuery { * @param onError the function to execute on error * @param settings a Properties object with the configuration of the Ajax request. */ - public static void ajaxOld(Settings settings) { + public static Promise ajax(Settings settings) { + final Deferred dfd = $().as(Deferred.Deferred); final Function onSuccess = settings.getSuccess(); if (onSuccess != null) { onSuccess.setElement(settings.getContext()); + dfd.promise().done(onSuccess); } final Function onError = settings.getError(); if (onError != null) { onError.setElement(settings.getContext()); + dfd.promise().fail(onError); } Method httpMethod = resolveHttpMethod(settings); @@ -127,20 +130,15 @@ public class Ajax extends GQuery { if ("jsonp".equalsIgnoreCase(dataType)) { int timeout = settings.getTimeout(); - getJSONP(url, onSuccess, onError, timeout); - return; + return getJSONP(url, onSuccess, onError, timeout); } final RequestBuilder requestBuilder = createRequestBuilder(settings, httpMethod, url, data); requestBuilder.setCallback(new RequestCallback() { public void onError(Request request, Throwable exception) { - if (onError != null) { - onError.f(null, exception.getMessage(), request, null, exception); - } + dfd.reject(null, exception.getMessage(), request, null, exception); } - - public void onResponseReceived(Request request, Response response) { int statusCode = response.getStatusCode(); if (statusCode <= 0 || statusCode >= 400) { @@ -148,9 +146,7 @@ public class Ajax extends GQuery { // Just warn the developer about the status code GWT.log("GQuery.ajax error, the response.statusCode is 0, this usually happens when you try to access an external server without CORS enabled. url=" + url); } - if (onError != null) { - onError.fe(response.getText(), "error", request, response); - } + dfd.reject(response.getText(), "error", request, response); } else if (onSuccess != null) { Object retData = null; try { @@ -166,7 +162,7 @@ public class Ajax extends GQuery { GWT.getUncaughtExceptionHandler().onUncaughtException(e); } } - onSuccess.fe(retData, "success", request, response); + dfd.resolve(retData, "success", request, response); } } }); @@ -174,14 +170,14 @@ public class Ajax extends GQuery { try { requestBuilder.send(); } catch (RequestException e) { - if (onError != null) { - onError.f(null, -1, null, null, e); - } + dfd.reject(null, e.getMessage(), null, null, e); } + + return dfd.promise(); } - public static Promise ajax(Settings settings) { + public static Promise ajaxNew(Settings settings) { final Deferred dfd = $().as(Deferred.Deferred); @@ -210,7 +206,7 @@ public class Ajax extends GQuery { RequestCallback mdb = new RequestCallback() { public void onError(Request request, Throwable exception) { if (onError != null) { - onError.f(null, exception.getMessage(), request, null, exception); + dfd.reject(null, exception.getMessage(), request, null, exception); } } @@ -247,22 +243,22 @@ public class Ajax extends GQuery { try { xmlHttpRequest.send(data); } catch (JavaScriptException e) { - dfd.reject(e.getMessage(), "error", null, null, e); + dfd.reject(null, e.getMessage(), null, null, e); } return dfd.promise(); } - + // Accessing protected constructor at XMLHttpRequest private static native Request createRequest(XMLHttpRequest r, int t, RequestCallback c) /*-{ return @com.google.gwt.http.client.Request::new(Lcom/google/gwt/xhr/client/XMLHttpRequest;ILcom/google/gwt/http/client/RequestCallback;)(r, t, c); }-*/; + // Accessing protected method at XMLHttpRequest private static native void fireOnResponseReceived(Request q, RequestCallback c) /*-{ q.@com.google.gwt.http.client.Request::fireOnResponseReceived(*)(c); }-*/; - private static XMLHttpRequest createXHR (Settings settings, String httpMethod, String url, String data, final RequestCallback cb) { XMLHttpRequest xmlHttpRequest = XMLHttpRequest.create(); @@ -413,34 +409,38 @@ public class Ajax extends GQuery { return s; } - public static void get(String url, Properties data, final Function onSuccess) { + public static Promise get(String url, Properties data, Function onSuccess) { Settings s = createSettings(); s.setUrl(url); s.setDataType("txt"); s.setType("get"); s.setData(data); s.setSuccess(onSuccess); - ajax(s); + return ajax(s); } - public static void getJSON(String url, Properties data, final Function onSuccess) { + public static Promise getJSON(String url, Properties data, Function onSuccess) { Settings s = createSettings(); s.setUrl(url); s.setDataType("json"); s.setType("post"); s.setData(data); s.setSuccess(onSuccess); - ajax(s); + return ajax(s); } - - public static void getJSONP(String url, Properties data, Function onSuccess) { + + public static Promise getJSONP(String url) { + return getJSONP(url, null, null, 0); + } + + public static Promise getJSONP(String url, Properties data, Function onSuccess) { Settings s = createSettings(); s.setUrl(url); s.setDataType("jsonp"); s.setType("get"); s.setData(data); s.setSuccess(onSuccess); - ajax(s); + return ajax(s); } public static Promise getJSONP(String url, Function success, Function error, int timeout) { @@ -458,14 +458,14 @@ public class Ajax extends GQuery { return dfd.promise(); } - public static void post(String url, Properties data, final Function onSuccess) { + public static Promise post(String url, Properties data, final Function onSuccess) { Settings s = createSettings(); s.setUrl(url); s.setDataType("txt"); s.setType("post"); s.setData(data); s.setSuccess(onSuccess); - ajax(s); + return ajax(s); } protected Ajax(GQuery gq) { @@ -512,7 +512,7 @@ public class Ajax extends GQuery { private static int callBackCounter = 0; - public static native void getJsonpImpl(Element elem, String url, String charset, Deferred dfd, int timeout) /*-{ + private static native void getJsonpImpl(Element elem, String url, String charset, Deferred dfd, int timeout) /*-{ var fName = "__GQ_cb_" + @com.google.gwt.query.client.plugins.ajax.Ajax::callBackCounter ++; var done = false; $wnd[fName] = function(data) { diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/callbacks/Callbacks.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/callbacks/Callbacks.java index 7ffd510a..14d3d59d 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/callbacks/Callbacks.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/callbacks/Callbacks.java @@ -162,15 +162,13 @@ public class Callbacks { } private void addAll(Object...o) { - if (stack != null) { - for (Object c : o) { - if (!opts.getUnique() || !stack.contains(c)) { - stack.add(c); - } - // In jQuery add always is run when memory is true even when unique is set - if (opts.getMemory() && memory != null) { - run(c, memory.elements()); - } + for (Object c : o) { + if (!done && (!opts.getUnique() || !stack.contains(c))) { + stack.add(c); + } + // In jQuery add always is run when memory is true even when unique is set + if (opts.getMemory() && memory != null) { + run(c, memory.elements()); } } } diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryDeferredTestGwt.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryDeferredTestGwt.java index c7ceb128..2cffb6d0 100644 --- a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryDeferredTestGwt.java +++ b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryDeferredTestGwt.java @@ -16,7 +16,10 @@ package com.google.gwt.query.client; +import static com.google.gwt.query.client.GQuery.when; + import com.google.gwt.junit.client.GWTTestCase; +import com.google.gwt.query.client.plugins.ajax.Ajax; import com.google.gwt.query.client.plugins.callbacks.Callbacks; import com.google.gwt.query.client.plugins.callbacks.Callbacks.Callback; @@ -141,5 +144,41 @@ public class GQueryDeferredTestGwt extends GWTTestCase { callbacks.add( fn1 ); assertEquals(" f1: bar f2: bar f2: bar f1: bar", result); } + + public void testDeferredAjaxWhenDone() { + String url = "https://www.googleapis.com/blogger/v2/blogs/user_id/posts/post_id?callback=?&key=NO-KEY"; + + delayTestFinish(5000); + + when(Ajax.getJSONP(url, null, null, 1000)) + .done(new Function() { + public void f() { + Properties p = getArgumentJSO(0, 0); + assertEquals(400, p.getJavaScriptObject("error").cast().getInt("code")); + finishTest(); + } + }); + } + + public void testDeferredAjaxWhenFail() { + String url1 = "https://www.googleapis.com/blogger/v2/blogs/user_id/posts/post_id?callback=?&key=NO-KEY"; + String url2 = "https://localhost:4569/foo"; + + delayTestFinish(5000); + + when( + Ajax.getJSONP(url1), + Ajax.getJSONP(url2, null, null, 1000)) + .done(new Function() { + public void f() { + fail(); + } + }) + .fail(new Function(){ + public void f() { + finishTest(); + } + }); + } }