blob: c4db8ad765f4fd8a50b2d2d1a0f0bef811928cf1 [file] [log] [blame]
/*
* Copyright 2011 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.storage.client;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.junit.client.GWTTestCase;
import com.google.gwt.user.client.Timer;
/**
* Tests {@link Storage}.
*/
public abstract class StorageTest extends GWTTestCase {
protected Storage storage;
protected StorageEvent.Handler handler;
protected StorageEvent.Handler handler2;
private native boolean isFirefox35OrLater() /*-{
var geckoVersion = @com.google.gwt.dom.client.DOMImplMozilla::getGeckoVersion()();
return (geckoVersion != -1) && (geckoVersion >= 1009001);
}-*/;
private native boolean isSafari3OrBefore() /*-{
return @com.google.gwt.dom.client.DOMImplWebkit::isWebkit525OrBefore()();
}-*/;
@Override
public String getModuleName() {
return "com.google.gwt.storage.Storage";
}
@Override
protected void gwtSetUp() throws Exception {
storage = getStorage();
if (storage == null) {
return; // do not run if not supported
}
// setup for tests by removing event handler
if (handler != null) {
storage.removeStorageEventHandler(handler);
handler = null;
}
if (handler2 != null) {
storage.removeStorageEventHandler(handler2);
handler2 = null;
}
// setup for tests by emptying storage
storage.clear();
}
@Override
protected void gwtTearDown() throws Exception {
if (storage == null) {
return; // do not run if not supported
}
// clean up by removing event handler
if (handler != null) {
storage.removeStorageEventHandler(handler);
handler = null;
}
if (handler2 != null) {
storage.removeStorageEventHandler(handler2);
handler2 = null;
}
// clean up by emptying storage
storage.clear();
}
/**
* Returns a {@link Storage} object.
*
* Override to return either a LocalStorage or a SessionStorage
*
* @return a {@link Storage} object
*/
abstract Storage getStorage();
public void testClear() {
if (storage == null) {
return; // do not run if not supported
}
storage.setItem("foo", "bar");
assertEquals(1, storage.getLength());
storage.clear();
assertEquals(0, storage.getLength());
}
public void testGet() {
if (storage == null) {
return; // do not run if not supported
}
storage.setItem("foo1", "bar1");
storage.setItem("foo2", "bar2");
assertEquals("bar1", storage.getItem("foo1"));
assertEquals("bar2", storage.getItem("foo2"));
// getting a value of a key that hasn't been set should return null
assertNull(
"Getting a value of a key that hasn't been set should return null",
storage.getItem("notset"));
}
public void testLength() {
if (storage == null) {
return; // do not run if not supported
}
storage.clear();
assertEquals(0, storage.getLength());
storage.setItem("abc", "def");
assertEquals(1, storage.getLength());
storage.setItem("ghi", "jkl");
assertEquals(2, storage.getLength());
storage.clear();
assertEquals(0, storage.getLength());
}
public void testSet() {
if (storage == null) {
return; // do not run if not supported
}
assertEquals(null, storage.getItem("foo"));
assertEquals(0, storage.getLength());
storage.setItem("foo", "bar1");
assertEquals("bar1", storage.getItem("foo"));
assertEquals(1, storage.getLength());
storage.setItem("foo", "bar2");
assertEquals("Should be able to overwrite an existing value", "bar2",
storage.getItem("foo"));
assertEquals(1, storage.getLength());
// test that using the empty string as a key throws an exception in devmode
if (!GWT.isScript()) {
try {
storage.setItem("", "baz");
throw new Error("Empty string should be disallowed as a key.");
} catch (AssertionError e) {
// expected
}
}
}
public void testKey() {
if (storage == null) {
return; // do not run if not supported
}
// key(n) where n >= storage.length() should return null
assertEquals(null, storage.key(0));
storage.setItem("a", "b");
assertEquals(null, storage.key(1));
storage.clear();
storage.setItem("foo1", "bar");
assertEquals("foo1", storage.key(0));
storage.setItem("foo2", "bar");
// key(0) should be either foo1 or foo2
assertTrue(storage.key(0).equals("foo1") || storage.key(0).equals("foo2"));
// foo1 should be either key(0) or key(1)
assertTrue(storage.key(0).equals("foo1") || storage.key(1).equals("foo1"));
// foo2 should be either key(0) or key(1)
assertTrue(storage.key(0).equals("foo2") || storage.key(1).equals("foo2"));
}
public void testRemoveItem() {
if (storage == null) {
return; // do not run if not supported
}
storage.setItem("foo1", "bar1");
storage.setItem("foo2", "bar2");
assertEquals("bar1", storage.getItem("foo1"));
assertEquals("bar2", storage.getItem("foo2"));
// removing a non-existent key should have no effect
storage.removeItem("abc");
assertEquals("bar1", storage.getItem("foo1"));
assertEquals("bar2", storage.getItem("foo2"));
// removing a key should remove that key and value
storage.removeItem("foo1");
assertEquals(null, storage.getItem("foo1"));
assertEquals("bar2", storage.getItem("foo2"));
storage.removeItem("foo2");
assertEquals(null, storage.getItem("foo2"));
}
public void testClearStorageEvent() {
if (storage == null) {
return; // do not run if not supported
}
delayTestFinish(2000);
storage.setItem("tcseFoo", "tcseBar");
handler = new StorageEvent.Handler() {
@Override
public void onStorageChange(StorageEvent event) {
assertNull(event.getKey());
assertNull(event.getOldValue());
assertNull(event.getNewValue());
assertEquals(storage, event.getStorageArea());
assertNotNull(event.getUrl());
finishTest();
}
};
storage.addStorageEventHandler(handler);
storage.clear();
}
public void testSetItemStorageEvent() {
if (storage == null) {
return; // do not run if not supported
}
delayTestFinish(2000);
storage.setItem("tsiseFoo", "tsiseBarOld");
handler = new StorageEvent.Handler() {
@Override
public void onStorageChange(StorageEvent event) {
assertEquals("tsiseFoo", event.getKey());
assertEquals("tsiseBarNew", event.getNewValue());
assertEquals("tsiseBarOld", event.getOldValue());
assertEquals(storage, event.getStorageArea());
assertNotNull(event.getUrl());
finishTest();
}
};
storage.addStorageEventHandler(handler);
storage.setItem("tsiseFoo", "tsiseBarNew");
}
public void testRemoveItemStorageEvent() {
if (storage == null) {
return; // do not run if not supported
}
delayTestFinish(2000);
storage.setItem("triseFoo", "triseBarOld");
handler = new StorageEvent.Handler() {
@Override
public void onStorageChange(StorageEvent event) {
assertEquals("triseFoo", event.getKey());
finishTest();
}
};
storage.addStorageEventHandler(handler);
storage.removeItem("triseFoo");
}
public void testHandlerRegistration() {
if (storage == null) {
return; // do not run if not supported
}
final boolean[] eventFired = new boolean[1];
eventFired[0] = false;
delayTestFinish(3000);
handler = new StorageEvent.Handler() {
@Override
public void onStorageChange(StorageEvent event) {
fail("Storage change should not have fired.");
eventFired[0] = true;
finishTest();
}
};
HandlerRegistration registration = storage.addStorageEventHandler(handler);
registration.removeHandler();
// these should fire events, but they should not be caught by handler
storage.setItem("thrFoo", "thrBar");
storage.clear();
// schedule timer to make sure event didn't fire async
new Timer() {
@Override
public void run() {
if (!eventFired[0]) {
finishTest();
}
}
}.schedule(1000);
}
public void testEventInEvent() {
if (storage == null) {
return; // do not run if not supported
}
delayTestFinish(3000);
storage.setItem("teieFoo", "teieBar");
handler = new StorageEvent.Handler() {
@Override
public void onStorageChange(StorageEvent event) {
if ("teieFoo".equals(event.getKey())) {
storage.clear();
storage.setItem("teieFoo2", "teieBar2");
// firing events from within a handler should not corrupt the values.
assertEquals("teieFoo", event.getKey());
storage.setItem("teieFooEndTest", "thanks");
}
if ("teieFooEndTest".equals(event.getKey())) {
finishTest();
}
}
};
storage.addStorageEventHandler(handler);
storage.removeItem("teieFoo");
}
public void testMultipleEventHandlers() {
if (storage == null) {
return; // do not run if not supported
}
delayTestFinish(3000);
final int[] eventHandledCount = new int[]{0};
storage.setItem("tmehFoo", "tmehBar");
handler = new StorageEvent.Handler() {
@Override
public void onStorageChange(StorageEvent event) {
if ("tmehFoo".equals(event.getKey())) {
eventHandledCount[0]++;
if (eventHandledCount[0] == 2) {
finishTest();
}
}
}
};
storage.addStorageEventHandler(handler);
handler2 = new StorageEvent.Handler() {
@Override
public void onStorageChange(StorageEvent event) {
if ("tmehFoo".equals(event.getKey())) {
eventHandledCount[0]++;
if (eventHandledCount[0] == 2) {
finishTest();
}
}
}
};
storage.addStorageEventHandler(handler2);
storage.removeItem("tmehFoo");
}
public void testEventStorageArea() {
if (storage == null) {
return; // do not run if not supported
}
delayTestFinish(2000);
storage.setItem("tesaFoo", "tesaBar");
handler = new StorageEvent.Handler() {
@Override
public void onStorageChange(StorageEvent event) {
Storage eventStorage = event.getStorageArea();
assertEquals(storage, eventStorage);
boolean equalsLocal = Storage.getLocalStorageIfSupported().equals(
eventStorage);
boolean equalsSession = Storage.getSessionStorageIfSupported().equals(
eventStorage);
// assert that storage is either local or session, but not both.
assertFalse(equalsLocal == equalsSession);
finishTest();
}
};
storage.addStorageEventHandler(handler);
storage.clear();
}
public void testSupported() {
// test the isxxxSupported() call
if (isFirefox35OrLater()) {
assertNotNull(storage);
assertTrue(Storage.isLocalStorageSupported());
assertTrue(Storage.isSessionStorageSupported());
assertTrue(Storage.isSupported());
}
if (isSafari3OrBefore()) {
assertNull(storage);
assertFalse(Storage.isLocalStorageSupported());
assertFalse(Storage.isSessionStorageSupported());
assertFalse(Storage.isSupported());
}
}
}