/* * 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; } public void onFailure(Throwable throwable) { if (id == currentTestId) { assertEquals(expectedMessage, throwable.getMessage()); finishTest(); } } 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; } public void onFailure(Throwable throwable) { if (id == currentTestId) { fail(); } } 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> { public void onFailure(Throwable throwable) { assertTrue(throwable instanceof TimeoutException); finishTest(); } 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")); } /** * Hangs indefinitely in devmode with HtmlUnit. * <p> * Call occurs through postponedActions in HtmlUnit that execute * synchronously. Should be async. Need to file HtmlUnitBug. */ @DoNotRunWith(Platform.HtmlUnitBug) public void testIds() { delayTestFinish(RESPONSE_DELAY); JsonpRequest<String> reqA = jsonp.requestString(echo("'A'"), new AssertSuccessCallback<String>("A")); JsonpRequest<String> reqB = jsonp.requestString(echo("'B'"), new AssertSuccessCallback<String>("B")); // 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() + 500); 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; } }