blob: a3d59daaf05767e116a328c4f0b4234dc6acc17f [file] [log] [blame]
/*
* Copyright 2009 Google Inc.
*
* 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.jsonp.client;
import com.google.gwt.core.client.GWT;
import com.google.gwt.junit.DoNotRunWith;
import com.google.gwt.junit.Platform;
import com.google.gwt.junit.client.GWTTestCase;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
/**
* Tests for {@link JsonpRequest}.
*/
public class JsonpRequestTest extends GWTTestCase {
/**
* Checks that an error is received.
*/
private class AssertFailureCallback<T> implements AsyncCallback<T> {
private String expectedMessage;
private int id;
public AssertFailureCallback(String expectedMessage) {
id = currentTestId;
this.expectedMessage = expectedMessage;
}
@Override
public void onFailure(Throwable throwable) {
if (id == currentTestId) {
assertEquals(expectedMessage, throwable.getMessage());
finishTest();
}
}
@Override
public void onSuccess(T value) {
if (id == currentTestId) {
fail();
}
}
}
/**
* Checks that the received value is as expected.
*/
private class AssertSuccessCallback<T> implements AsyncCallback<T> {
private final T expectedValue;
private final int id;
private final Counter counter;
private AssertSuccessCallback(T expectedValue) {
this(expectedValue, null);
}
private AssertSuccessCallback(T expectedValue, Counter counter) {
this.id = currentTestId;
this.counter = counter;
this.expectedValue = expectedValue;
}
@Override
public void onFailure(Throwable throwable) {
if (id == currentTestId) {
fail();
}
}
@Override
public void onSuccess(T value) {
if (id == currentTestId) {
assertEquals(expectedValue, value);
if (counter != null) {
counter.count();
} else {
finishTest();
}
}
}
}
/**
* Checks that a timeout happens.
*/
private class AssertTimeoutExceptionCallback<T> implements AsyncCallback<T> {
@Override
public void onFailure(Throwable throwable) {
assertTrue(throwable instanceof TimeoutException);
finishTest();
}
@Override
public void onSuccess(T value) {
fail();
}
}
/**
* A class that counts results and calls finishTest when the right number
* have been received.
*/
private class Counter {
private int count;
public Counter(int count) {
this.count = count;
}
public void count() {
if (--count < 0) {
fail("Too many results");
}
if (count == 0) {
finishTest();
}
}
}
/**
* The maximum amount of time to wait for a response in milliseconds.
*/
private static final int RESPONSE_DELAY = 2500;
/**
* The ID of the current test.
*/
protected static int currentTestId;
private static String echo(String value) {
return GWT.getModuleBaseURL() + "echo?action=SUCCESS&value=" + value;
}
private static String echoDelayed(String value) {
return echoDelayed(value, 500);
}
private static String echoDelayed(String value, long delayMs) {
return GWT.getModuleBaseURL() + "echo?action=SUCCESS&delay=" + delayMs
+ "&value=" + value;
}
private static String echoFailure(String error) {
return GWT.getModuleBaseURL() + "echo?action=FAILURE&error=" + error;
}
private static String echoTimeout() {
return GWT.getModuleBaseURL() + "echo?action=TIMEOUT";
}
private JsonpRequestBuilder jsonp;
@Override
public String getModuleName() {
return "com.google.gwt.jsonp.JsonpTest";
}
public void testBooleanFalse() {
delayTestFinish(RESPONSE_DELAY);
jsonp.requestBoolean(echo("false"), new AssertSuccessCallback<Boolean>(
Boolean.FALSE));
}
public void testBooleanTrue() {
delayTestFinish(RESPONSE_DELAY);
jsonp.requestBoolean(echo("true"), new AssertSuccessCallback<Boolean>(
Boolean.TRUE));
}
/**
* Fails in devmode with HtmlUnit, JS "null" exception.
* <p>
* Call occurs through postponedActions in HtmlUnit that execute
* synchronously. Should be async. Need to file HtmlUnitBug.
*/
@DoNotRunWith(Platform.HtmlUnitBug)
public void testCancel() {
delayTestFinish(2000);
// setup a server request that will delay for 500ms
JsonpRequest<String> req = jsonp.requestString(echoDelayed("'A'", 500),
new AssertFailureCallback<String>("A"));
// cancel it before it comes back
req.cancel();
// wait 1s to make sure we don't get a callback
new Timer() {
@Override
public void run() {
finishTest();
}
}.schedule(1000);
}
public void testDelay() {
delayTestFinish(RESPONSE_DELAY);
JsonpRequest<String> req = jsonp.requestString(echoDelayed("'A'"),
new AssertSuccessCallback<String>("A"));
}
public void testDouble() {
delayTestFinish(RESPONSE_DELAY);
jsonp.requestDouble(echo("123.456"), new AssertSuccessCallback<Double>(
123.456));
}
public void testFailureCallback() {
delayTestFinish(RESPONSE_DELAY);
jsonp.setFailureCallbackParam("failureCallback");
jsonp.requestString(echoFailure("ERROR"),
new AssertFailureCallback<String>("ERROR"));
}
public void testIds() {
delayTestFinish(RESPONSE_DELAY);
Counter counter = new Counter(2);
JsonpRequest<String> reqA = jsonp.requestString(echo("'A'"),
new AssertSuccessCallback<String>("A", counter));
JsonpRequest<String> reqB = jsonp.requestString(echo("'B'"),
new AssertSuccessCallback<String>("B", counter));
// WARNING: knows the current structure of IDs
int idA = Integer.parseInt(reqA.getCallbackId().substring(1));
int idB = Integer.parseInt(reqB.getCallbackId().substring(1));
assertEquals("Unexpected ID sequence", idA + 1, idB);
}
public void testInteger() {
delayTestFinish(RESPONSE_DELAY);
jsonp.requestInteger(echo("123"), new AssertSuccessCallback<Integer>(123));
}
/**
* Tests that if no failure callback is defined, the servlet receives well
* only a 'callback' parameter, and sends back the error to it.
*/
public void testNoFailureCallback() {
delayTestFinish(RESPONSE_DELAY);
jsonp.setFailureCallbackParam(null);
jsonp.requestString(echoFailure("ERROR"),
new AssertSuccessCallback<String>("ERROR"));
}
public void testNullBoolean() {
delayTestFinish(RESPONSE_DELAY);
jsonp.requestBoolean(echo("null"), new AssertSuccessCallback<Boolean>(null));
}
public void testNullDouble() {
delayTestFinish(RESPONSE_DELAY);
jsonp.requestDouble(echo("null"), new AssertSuccessCallback<Double>(null));
}
public void testNullInteger() {
delayTestFinish(RESPONSE_DELAY);
jsonp.requestInteger(echo("null"), new AssertSuccessCallback<Integer>(null));
}
public void testNullString() {
delayTestFinish(RESPONSE_DELAY);
jsonp.requestString(echo("null"), new AssertSuccessCallback<String>(null));
}
public void testOverlapped() {
delayTestFinish(RESPONSE_DELAY);
Counter counter = new Counter(3);
JsonpRequest<String> reqA = jsonp.requestString(echoDelayed("'A'", 750),
new AssertSuccessCallback<String>("A", counter));
JsonpRequest<String> reqB = jsonp.requestString(echoDelayed("'B'", 500),
new AssertSuccessCallback<String>("B", counter));
JsonpRequest<String> reqC = jsonp.requestString(echo("'C'"),
new AssertSuccessCallback<String>("C", counter));
}
public void testPredeterminedIds() {
delayTestFinish(RESPONSE_DELAY);
String PREDETERMINED = "pred";
jsonp.setPredeterminedId(PREDETERMINED);
JsonpRequest<String> reqA = jsonp.requestString(echo("'A'"),
new AssertSuccessCallback<String>("A"));
String idA = reqA.getCallbackId().substring(1);
assertEquals("Unexpected ID sequence", PREDETERMINED, idA);
jsonp.setPredeterminedId(null);
}
public void testString() {
delayTestFinish(RESPONSE_DELAY);
jsonp.requestString(echo("'Hello'"), new AssertSuccessCallback<String>(
"Hello"));
}
public void testTimeout() {
delayTestFinish(jsonp.getTimeout() + 1000);
jsonp.requestString(echoTimeout(),
new AssertTimeoutExceptionCallback<String>());
}
public void testVoid() {
delayTestFinish(RESPONSE_DELAY);
jsonp.send(echo(null), new AssertSuccessCallback<Void>(null));
}
@Override
protected void gwtSetUp() throws Exception {
jsonp = new JsonpRequestBuilder();
jsonp.setTimeout(RESPONSE_DELAY + 500);
}
@Override
protected void gwtTearDown() throws Exception {
++currentTestId;
}
}