/*
* Copyright 2011, The gwtquery team.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.query.client.deferred;
import static com.google.gwt.query.client.GQuery.*;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.junit.client.GWTTestCase;
import com.google.gwt.query.client.Function;
import com.google.gwt.query.client.GQuery;
import com.google.gwt.query.client.Promise.Deferred;
import com.google.gwt.query.client.plugins.deferred.Callbacks;
import com.google.gwt.query.client.plugins.deferred.Callbacks.Callback;
import com.google.gwt.query.client.plugins.deferred.FunctionDeferred.CacheType;
import com.google.gwt.query.client.plugins.deferred.FunctionDeferred;
import com.google.gwt.query.client.plugins.deferred.PromiseFunction;
/**
* Tests for Deferred which can run either in JVM and GWT
*/
public class DeferredTest extends GWTTestCase {
public String getModuleName() {
return null;
}
private String result = "";
public void testCallbacks() {
final Function fn1 = new Function() {
public Object f(Object...arguments) {
String s = " f1:";
for (Object o: arguments){
s += " " + o;
}
result += s;
return false;
}
};
final Callback fn2 = new Callback() {
public boolean f(Object... objects) {
String s = " f2:";
for (Object o: objects){
s += " " + o;
}
result += s;
return false;
}
};
com.google.gwt.core.client.Callback<Object, Object> fn3 = new com.google.gwt.core.client.Callback<Object, Object>() {
public void onFailure(Object reason) {
result += " f3_fail: " + reason;
}
public void onSuccess(Object objects) {
String s = " f3_success:";
for (Object o: (Object[])objects){
s += " " + o;
}
result += s;
}
};
result = "";
Callbacks callbacks = new Callbacks();
callbacks.add( fn1 );
callbacks.fire( "foo" );
assertEquals(" f1: foo", result);
result = "";
callbacks.add( fn2 );
callbacks.fire( "bar" );
assertEquals(" f1: bar f2: bar", result);
result = "";
callbacks.remove( fn2 );
callbacks.fire( "foobar" );
assertEquals(" f1: foobar", result);
result = "";
callbacks.add( fn1 );
callbacks.fire( "foo" );
assertEquals(" f1: foo f1: foo", result);
result = "";
callbacks = new Callbacks("unique");
callbacks.add( fn1 );
callbacks.add( fn1 );
callbacks.fire( "foo" );
assertEquals(" f1: foo", result);
result = "";
callbacks.add( fn3 );
callbacks.fire( "bar" );
assertEquals(" f1: bar f3_success: bar", result);
result = "";
callbacks = new Callbacks("memory");
callbacks.add( fn1 );
callbacks.fire( "foo" );
callbacks.add( fn2 );
callbacks.fire( "bar" );
callbacks.remove(fn2);
callbacks.fire( "foobar" );
assertEquals(" f1: foo f2: foo f1: bar f2: bar f1: foobar", result);
result = "";
callbacks = new Callbacks("stopOnFalse");
callbacks.add( fn1 );
callbacks.add( fn2 );
callbacks.fire( "bar" );
assertEquals(" f1: bar", result);
result = "";
callbacks.disable();
callbacks.fire( "bar" );
assertEquals("", result);
result = "";
callbacks = new Callbacks("memory once unique");
callbacks.add( fn1 );
callbacks.add( fn1 );
callbacks.fire( "bar" );
assertEquals(" f1: bar", result);
callbacks.fire( "foo" );
assertEquals(" f1: bar", result);
callbacks.add( fn2 );
callbacks.add( fn2 );
assertEquals(" f1: bar f2: bar f2: bar", result);
callbacks.remove( fn1 );
callbacks.add( fn1 );
assertEquals(" f1: bar f2: bar f2: bar f1: bar", result);
callbacks.remove( fn1 );
callbacks.disable();
callbacks.add( fn1 );
assertEquals(" f1: bar f2: bar f2: bar f1: bar f1: bar", result);
// Test adding callback functions in nested executions
result = "";
final Callbacks callbacks2 = new Callbacks("memory once unique");
callbacks2.add(fn1);
callbacks2.add(new Function(){public void f() {
callbacks2.add( fn2 );
}});
callbacks2.fire("foo");
assertEquals(" f1: foo f2: foo", result);
}
public void testThen() {
new PromiseFunction() {
public void f(final Deferred dfd) {
dfd.resolve(5d);
}
}.done(new Function() {
public void f() {
assertEquals(5d, arguments(0));
}
}).then(new Function() {
public Object f(Object... args) {
return (Double)args[0] * 2;
}
}).done(new Function() {
public void f() {
assertEquals(10d, arguments(0));
}
});
}
// In JVM delayTestFinish does not make the test fail if finishTest()
// is not called, so we use a done flag in tests using it
// to verify .done() has been run
private boolean done;
public void testDone() {
done = false;
delayTestFinish(5000);
when(new PromiseFunction() {public void f(Deferred dfd) {
dfd.resolve("Hi");
}}).done(new Function(){public void f() {
assertEquals("Hi", arguments(0));
finishTest();
done = true;
}});
if (!GWT.isClient()) {
assertTrue(done);
}
}
public void testDeferredThenDone() {
done = false;
delayTestFinish(5000);
GQuery
.when(new PromiseFunction() {
public void f(Deferred dfd) {
dfd.resolve("message");
}
})
.and(new FunctionDeferred() {
public void f(Deferred dfd) {
dfd.resolve("then1 " + arguments[0]);
}
})
.then(new FunctionDeferred() {
public void f(Deferred dfd) {
dfd.resolve("then2 " + arguments[0]);
}
})
.fail(new Function() {
public void f() {
finishTest();
fail();
}
})
.done(new Function() {
public void f() {
assertEquals("then2 then1 message", arguments(0));
finishTest();
done = true;
}
});
if (!GWT.isClient()) {
assertTrue(done);
}
}
public void testDeferredThenFail() {
done = false;
delayTestFinish(5000);
GQuery
.when(new PromiseFunction() {
public void f(Deferred dfd) {
dfd.resolve("message");
}
})
.and(new Function(){
public Object f(Object... data) {
return (arguments[0] + " then1");
}
})
.then(new Function(){
public void f() {
// should return the previous value
}
})
.then(new FunctionDeferred() {
public void f(Deferred dfd) {
dfd.reject("then2 " + arguments[0]);
}
})
.then(new FunctionDeferred() {
public void f(Deferred dfd) {
dfd.resolve("then3 " + arguments[0]);
}
})
.done(new Function() {
public void f() {
finishTest();
fail();
}
})
.fail(new Function() {
public void f() {
assertEquals("then2 message then1", arguments(0));
finishTest();
done = true;
}
});
if (!GWT.isClient()) {
assertTrue(done);
}
}
public void testDeferredOr() {
done = false;
delayTestFinish(5000);
GQuery
.when(new PromiseFunction() {
public void f(Deferred dfd) {
dfd.reject("reject-when");
}
})
.or(new FunctionDeferred() {
public void f(Deferred dfd) {
dfd.reject(arguments[0] + " reject-or1");
}
})
.or(new FunctionDeferred() {
public void f(Deferred dfd) {
dfd.reject(arguments[0] + " reject-or2");
}
})
.or(new FunctionDeferred() {
public void f(Deferred dfd) {
dfd.resolve(arguments[0] + " resolve-or3");
}
})
.or(new FunctionDeferred() {
public void f(Deferred dfd) {
dfd.resolve(arguments[0] + " or4");
}
})
.or(new FunctionDeferred() {
public void f(Deferred dfd) {
dfd.reject(arguments[0] + " or5");
}
})
.done(new Function() {
public void f() {
assertEquals("reject-when reject-or1 reject-or2 resolve-or3", arguments(0));
finishTest();
done = true;
}
})
.fail(new Function() {
public void f() {
finishTest();
fail();
}
});
if (!GWT.isClient()) {
assertTrue(done);
}
}
public void testProtected() {
delayTestFinish(20);
GQuery.when(new PromiseFunction() {
public void f(final Deferred dfd) {
GQuery.when(new Function() {
public void f() {
// This causes an '...IllegalAccessError: tried to access class ...Deferred$DeferredPromiseImpl ...'
// in dev-mode when resolve is protected. It works in JRE and production though.
resolve.f();
}
});
}
}).then(new FunctionDeferred() {
protected void f(Deferred dfd) {
GQuery.when(new Function() {
public void f() {
resolve.f();
}
});
}
}).done(new Function() {
public void f() {
finishTest();
}
});
}
private Boolean deferredData;
public void testFunctionDeferredCache() {
FunctionDeferred cachedFunction = new FunctionDeferred() {
protected void f(Deferred dfd) {
dfd.resolve(deferredData);
}
};
Function setDeferredDataToTrue = new Function(){
public void f() {
deferredData = true;
}
};
Function setDeferredDataToFalse = new Function() {
public void f() {
deferredData = false;
}
};
Function assertDeferredDataIsFalse = new Function() {
public void f() {
Boolean data = arguments(0);
assertFalse(data);
}
};
Function assertDeferredDataIsTrue = new Function() {
public void f() {
Boolean data = arguments(0);
assertTrue(data);
}
};
when(setDeferredDataToTrue, cachedFunction.withCache(CacheType.ALL))
.always(setDeferredDataToFalse)
.done(assertDeferredDataIsTrue)
.then(cachedFunction)
.done(assertDeferredDataIsTrue)
.then(cachedFunction.withCache(CacheType.REJECTED))
.done(assertDeferredDataIsFalse)
.always(setDeferredDataToTrue)
.then(cachedFunction.withCache(CacheType.RESOLVED))
.done(assertDeferredDataIsFalse)
.then(cachedFunction.resetCache())
.done(assertDeferredDataIsTrue)
.then(cachedFunction)
.done(assertDeferredDataIsTrue)
;
}
}