| /* |
| * 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()); |
| } |
| } |
| } |