/*
* Copyright 2012 Johannes Barop
*
* 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 de.barop.gwt.client;
import java.util.Stack;
import org.timepedia.exporter.client.Export;
import org.timepedia.exporter.client.Exportable;
import org.timepedia.exporter.client.ExporterUtil;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.junit.client.GWTTestCase;
import com.google.gwt.user.client.History;
/**
* Base class for GWT unit tests with mocked pushState support.
*
* <p>
* The embedded HtmlUnit FF3 browser does not have pushState support. In order to unit test it
* easily the pushState API is mocked.
* </p>
*
* @author <a href="mailto:jb@barop.de">Johannes Barop</a>
*
*/
public abstract class AbstractPushStateTest extends GWTTestCase {
/**
* A pushed history state.
*/
static class State {
final JavaScriptObject data;
final String title;
final String url;
State(final JavaScriptObject data, final String title, final String url) {
this.data = data;
this.title = title;
this.url = url;
}
@Override
public String toString() {
return "State [data=" + data + ", title=" + title + ", url=" + url + "]";
}
}
/**
* The pushState implementation which gets exported to JavaScript.
*/
public static class PushStateApi implements Exportable {
@Export("$wnd.history.pushState")
public static void pushState(final JavaScriptObject data, final String title, final String url) {
states.push(new State(data, title, url));
}
}
/**
* All pushed states.
*/
protected static Stack<State> states;
/**
* The number of the items in {@link #states} at test start.
*/
protected int statesOnTestStart;
@Override
public String getModuleName() {
return "de.barop.gwt.PushStateTest";
}
@Override
protected void gwtSetUp() throws Exception {
super.gwtSetUp();
if (states == null) {
ExporterUtil.exportAll();
states = new Stack<State>();
GWT.create(History.class);
}
statesOnTestStart = states.size();
}
/**
* Set's the hash part of the browsers address bar.
*/
protected native void setHash(String hash) /*-{
$wnd.location.hash = hash;
}-*/;
/**
* Pop the previous history state.
*/
protected void popState() {
assert states.size() > 1;
states.pop(); // go back
callOnPopState(states.peek().data); // pop the current state
}
/**
* Native JavaScript which calls the onpopstate handler with the given state.
*/
private native void callOnPopState(JavaScriptObject data) /*-{
var event = {
state : data
};
$wnd.onpopstate(event);
}-*/;
/**
* Assert that the test runs with pushState support.
*/
public void testNoPushStateSupport() {
assertTrue(GWT.create(HistoryConverter.class) instanceof HistoryConverterPushState);
}
}