| /* |
| * Copyright 2008 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.user.client.ui; |
| |
| import com.google.gwt.core.client.GWT; |
| import com.google.gwt.dom.client.DivElement; |
| import com.google.gwt.dom.client.Document; |
| import com.google.gwt.dom.client.Element; |
| import com.google.gwt.event.dom.client.ErrorEvent; |
| import com.google.gwt.event.dom.client.ErrorHandler; |
| import com.google.gwt.event.dom.client.LoadEvent; |
| import com.google.gwt.event.dom.client.LoadHandler; |
| import com.google.gwt.junit.DoNotRunWith; |
| import com.google.gwt.junit.Platform; |
| import com.google.gwt.junit.client.GWTTestCase; |
| import com.google.gwt.junit.client.WithProperties; |
| import com.google.gwt.junit.client.WithProperties.Property; |
| import com.google.gwt.resources.client.ClientBundle; |
| import com.google.gwt.resources.client.ImageResource; |
| import com.google.gwt.resources.client.ImageResource.ImageOptions; |
| import com.google.gwt.resources.client.impl.ImageResourcePrototype; |
| import com.google.gwt.user.client.Timer; |
| |
| /** |
| * Tests for the Image widget. Images in both clipped mode and unclipped mode |
| * are tested, along with the transitions between the two modes. |
| */ |
| public class ImageTest extends GWTTestCase { |
| interface Bundle extends ClientBundle { |
| ImageResource prettyPiccy(); |
| |
| @Source("prettyPiccy.png") |
| @ImageOptions(preventInlining = true) |
| ImageResource prettyPiccyStandalone(); |
| } |
| |
| private static class TestErrorHandler implements ErrorHandler { |
| private Image image; |
| |
| public TestErrorHandler(Image image) { |
| this.image = image; |
| } |
| |
| @Override |
| public void onError(ErrorEvent event) { |
| fail("The image " + image.getUrl() + " failed to load."); |
| } |
| } |
| |
| private static class TestImage extends Image { |
| public TestImage(Element element) { |
| super(element); |
| } |
| |
| public static TestImage wrap(Element element) { |
| // Assert that the element is attached. |
| assert Document.get().getBody().isOrHasChild(element); |
| |
| TestImage image = new TestImage(element); |
| |
| // Mark it attached and remember it for cleanup. |
| image.onAttach(); |
| RootPanel.detachOnWindowClose(image); |
| |
| return image; |
| } |
| } |
| |
| private abstract static class TestLoadHandler implements LoadHandler { |
| private boolean finished = false; |
| |
| /** |
| * Mark the test as finished. |
| */ |
| public void finish() { |
| finished = true; |
| } |
| |
| /** |
| * Returns true if the test has finished. |
| */ |
| public boolean isFinished() { |
| return finished; |
| } |
| } |
| |
| @Deprecated |
| private abstract static class TestLoadListener implements LoadListener { |
| private boolean finished = false; |
| private Image image; |
| |
| public TestLoadListener(Image image) { |
| this.image = image; |
| } |
| |
| /** |
| * Mark the test as finished. |
| */ |
| public void finish() { |
| finished = true; |
| } |
| |
| /** |
| * Returns true if the test has finished. |
| */ |
| public boolean isFinished() { |
| return finished; |
| } |
| |
| @Override |
| public void onError(Widget sender) { |
| fail("The image " + image.getUrl() + " failed to load."); |
| } |
| } |
| |
| /** |
| * The default timeout of asynchronous tests. This should be larger than |
| * LOAD_EVENT_TIMEOUT and SYNTHETIC_LOAD_EVENT_TIMEOUT. |
| */ |
| private static final int DEFAULT_TEST_TIMEOUT = 10000; |
| |
| /** |
| * The amount of time to wait for a load event to fire in milliseconds. |
| */ |
| private static final int LOAD_EVENT_TIMEOUT = 7000; |
| |
| /** |
| * The amount of time to wait for a clipped image to fire a synthetic load |
| * event in milliseconds. |
| */ |
| private static final int SYNTHETIC_LOAD_EVENT_TIMEOUT = 1000; |
| |
| /** |
| * Helper method that allows us to 'peek' at the private <code>state</code> |
| * field in the Image object, and call the <code>state.getStateName()</code> |
| * method. |
| * |
| * @param image The image instance |
| * @return "unclipped" if image is in the unclipped state, or "clipped" if the |
| * image is in the clipped state |
| */ |
| public static native String getCurrentImageStateName(Image image) /*-{ |
| var imgState = image.@com.google.gwt.user.client.ui.Image::state; |
| return imgState.@com.google.gwt.user.client.ui.Image.State::getStateName() (); |
| }-*/; |
| |
| private int firedError; |
| |
| private int firedLoad; |
| |
| @Override |
| public String getModuleName() { |
| return "com.google.gwt.user.UserTest"; |
| } |
| |
| public void testAltText() { |
| final String altText = "this is an image"; |
| final Image image = new Image("image.png", 12, 12, 12, 12); |
| |
| assertEquals("", image.getAltText()); |
| image.setAltText(altText); |
| assertEquals(altText, image.getAltText()); |
| image.setAltText(""); |
| assertEquals("", image.getAltText()); |
| } |
| |
| /** |
| * Test that attaching and immediately detaching an element does not cause an |
| * error. |
| */ |
| public void testAttachDetach() { |
| |
| final Image image = new Image("counting-forwards.png"); |
| RootPanel.get().add(image); |
| RootPanel.get().remove(image); |
| |
| // Wait for the synthetic event to attempt to fire. |
| delayTestFinish(DEFAULT_TEST_TIMEOUT); |
| new Timer() { |
| @Override |
| public void run() { |
| // The synthetic event did not cause an error. |
| finishTest(); |
| } |
| }.schedule(SYNTHETIC_LOAD_EVENT_TIMEOUT); |
| } |
| |
| /** |
| * Tests the transition from the clipped state to the unclipped state. |
| */ |
| @DoNotRunWith(Platform.HtmlUnitUnknown) |
| public void testChangeClippedImageToUnclipped() { |
| final Image image = new Image("counting-forwards.png", 12, 13, 8, 8); |
| assertEquals("clipped", getCurrentImageStateName(image)); |
| |
| delayTestFinish(DEFAULT_TEST_TIMEOUT); |
| image.addErrorHandler(new TestErrorHandler(image)); |
| image.addLoadHandler(new LoadHandler() { |
| private int onLoadEventCount = 0; |
| |
| @Override |
| public void onLoad(LoadEvent event) { |
| ++onLoadEventCount; |
| if (onLoadEventCount == 1) { // Set the url after the first image loads |
| image.setUrl("counting-forwards.png"); |
| } else if (onLoadEventCount == 2) { |
| assertEquals(0, image.getOriginLeft()); |
| assertEquals(0, image.getOriginTop()); |
| assertEquals(32, image.getWidth()); |
| assertEquals(32, image.getHeight()); |
| assertEquals("unclipped", getCurrentImageStateName(image)); |
| finishTest(); |
| } |
| } |
| }); |
| |
| RootPanel.get().add(image); |
| } |
| |
| /** |
| * Tests the transition from the unclipped state to the clipped state. |
| */ |
| @DoNotRunWith(Platform.HtmlUnitUnknown) |
| public void testChangeImageToClipped() { |
| final Image image = new Image("counting-forwards.png"); |
| assertEquals("unclipped", getCurrentImageStateName(image)); |
| |
| delayTestFinish(DEFAULT_TEST_TIMEOUT); |
| image.addErrorHandler(new TestErrorHandler(image)); |
| image.addLoadHandler(new LoadHandler() { |
| private int onLoadEventCount = 0; |
| |
| @Override |
| public void onLoad(LoadEvent event) { |
| if (getCurrentImageStateName(image).equals("unclipped")) { |
| image.setVisibleRect(12, 13, 8, 8); |
| } |
| |
| if (++onLoadEventCount == 2) { |
| assertEquals(12, image.getOriginLeft()); |
| assertEquals(13, image.getOriginTop()); |
| assertEquals(8, image.getWidth()); |
| assertEquals(8, image.getHeight()); |
| assertEquals("clipped", getCurrentImageStateName(image)); |
| finishTest(); |
| } |
| } |
| }); |
| |
| RootPanel.get().add(image); |
| } |
| |
| /** |
| * Tests the transition from the unclipped state to the clipped state |
| * before a load event fires. |
| */ |
| @DoNotRunWith(Platform.HtmlUnitUnknown) |
| public void testChangeImageToClippedSynchronously() { |
| |
| final Image image = new Image("counting-forwards.png"); |
| assertEquals("unclipped", getCurrentImageStateName(image)); |
| |
| image.addErrorHandler(new TestErrorHandler(image)); |
| final TestLoadHandler loadHandler = new TestLoadHandler() { |
| @Override |
| public void onLoad(LoadEvent event) { |
| if (isFinished()) { |
| fail("LoadHandler fired twice. Expected it to fire only once."); |
| } |
| |
| assertEquals("clipped", getCurrentImageStateName(image)); |
| assertEquals(12, image.getOriginLeft()); |
| assertEquals(13, image.getOriginTop()); |
| assertEquals(8, image.getWidth()); |
| assertEquals(8, image.getHeight()); |
| finish(); |
| } |
| }; |
| image.addLoadHandler(loadHandler); |
| |
| /* |
| * Change the image to a clipped image before a load event fires. We only |
| * expect one asynchronous load event to fire for the final state. This is |
| * consistent with the expected behavior of changing the source URL multiple |
| * times. |
| */ |
| RootPanel.get().add(image); |
| image.setVisibleRect(12, 13, 8, 8); |
| assertEquals("clipped", getCurrentImageStateName(image)); |
| |
| delayTestFinish(DEFAULT_TEST_TIMEOUT); |
| new Timer() { |
| @Override |
| public void run() { |
| assertTrue(loadHandler.isFinished()); |
| finishTest(); |
| } |
| }.schedule(SYNTHETIC_LOAD_EVENT_TIMEOUT); |
| } |
| |
| /** |
| * Tests the creation of an image in unclipped mode. |
| */ |
| public void testCreateImage() { |
| final Image image = new Image("counting-forwards.png"); |
| |
| delayTestFinish(DEFAULT_TEST_TIMEOUT); |
| image.addErrorHandler(new TestErrorHandler(image)); |
| image.addLoadHandler(new LoadHandler() { |
| private int onLoadEventCount = 0; |
| |
| @Override |
| public void onLoad(LoadEvent event) { |
| if (++onLoadEventCount == 1) { |
| assertEquals(32, image.getWidth()); |
| assertEquals(32, image.getHeight()); |
| finishTest(); |
| } |
| } |
| }); |
| |
| RootPanel.get().add(image); |
| assertEquals(0, image.getOriginLeft()); |
| assertEquals(0, image.getOriginTop()); |
| assertEquals("unclipped", getCurrentImageStateName(image)); |
| } |
| |
| /** |
| * Tests the creation of an image that does not exist. |
| */ |
| @DoNotRunWith(Platform.HtmlUnitUnknown) |
| public void testCreateImageWithError() { |
| final Image image = new Image("imageDoesNotExist.png"); |
| |
| delayTestFinish(DEFAULT_TEST_TIMEOUT); |
| image.addErrorHandler(new ErrorHandler() { |
| @Override |
| public void onError(ErrorEvent event) { |
| finishTest(); |
| } |
| }); |
| image.addLoadHandler(new LoadHandler() { |
| @Override |
| public void onLoad(LoadEvent event) { |
| fail("The image " + image.getUrl() + " should have failed to load."); |
| } |
| }); |
| |
| RootPanel.get().add(image); |
| } |
| |
| /** |
| * Tests the firing of onload events when |
| * {@link com.google.gwt.user.client.ui.Image#setUrl(String)} is called on an |
| * unclipped image. |
| */ |
| public void testSetUrlAndLoadEventsOnUnclippedImage() { |
| final Image image = new Image(); |
| |
| delayTestFinish(DEFAULT_TEST_TIMEOUT); |
| image.addErrorHandler(new TestErrorHandler(image)); |
| image.addLoadHandler(new LoadHandler() { |
| private int onLoadEventCount = 0; |
| |
| @Override |
| public void onLoad(LoadEvent event) { |
| if (++onLoadEventCount == 2) { |
| finishTest(); |
| } else { |
| image.setUrl("counting-forwards.png"); |
| } |
| } |
| }); |
| |
| RootPanel.get().add(image); |
| image.setUrl("counting-backwards.png"); |
| } |
| |
| /** |
| * Tests the behavior of |
| * <code>setUrlAndVisibleRect(String, int, int, int, int)</code> method on an |
| * unclipped image, which causes a state transition to the clipped state. |
| */ |
| @DoNotRunWith(Platform.HtmlUnitUnknown) |
| public void testSetUrlAndVisibleRectOnUnclippedImage() { |
| final Image image = new Image("counting-backwards.png"); |
| assertEquals("unclipped", getCurrentImageStateName(image)); |
| |
| delayTestFinish(DEFAULT_TEST_TIMEOUT); |
| image.addErrorHandler(new TestErrorHandler(image)); |
| image.addLoadHandler(new LoadHandler() { |
| private int onLoadEventCount = 0; |
| |
| @Override |
| public void onLoad(LoadEvent event) { |
| if (getCurrentImageStateName(image).equals("unclipped")) { |
| image.setUrlAndVisibleRect("counting-forwards.png", 0, 16, 16, 16); |
| } |
| |
| if (++onLoadEventCount == 2) { |
| assertEquals(0, image.getOriginLeft()); |
| assertEquals(16, image.getOriginTop()); |
| assertEquals(16, image.getWidth()); |
| assertEquals(16, image.getHeight()); |
| assertEquals("clipped", getCurrentImageStateName(image)); |
| finishTest(); |
| } |
| } |
| }); |
| |
| RootPanel.get().add(image); |
| } |
| |
| /** |
| * Tests the creation of an image in clipped mode. |
| */ |
| @SuppressWarnings("deprecation") |
| public void testCreateClippedImage() { |
| final Image image = new Image("counting-forwards.png", 16, 16, 16, 16); |
| |
| delayTestFinish(DEFAULT_TEST_TIMEOUT); |
| final TestLoadListener listener = new TestLoadListener(image) { |
| private int onLoadEventCount = 0; |
| |
| @Override |
| public void onLoad(Widget sender) { |
| if (++onLoadEventCount == 1) { |
| assertEquals(16, image.getWidth()); |
| assertEquals(16, image.getHeight()); |
| finish(); |
| } |
| } |
| }; |
| image.addLoadListener(listener); |
| |
| image.addLoadHandler(new LoadHandler() { |
| private int onLoadEventCount = 0; |
| |
| @Override |
| public void onLoad(LoadEvent event) { |
| if (++onLoadEventCount == 1) { |
| assertEquals(16, image.getWidth()); |
| assertEquals(16, image.getHeight()); |
| if (listener.isFinished()) { |
| finishTest(); |
| } else { |
| fail("Listener did not fire first"); |
| } |
| } |
| } |
| }); |
| image.addErrorHandler(new TestErrorHandler(image)); |
| |
| RootPanel.get().add(image); |
| assertEquals(16, image.getOriginLeft()); |
| assertEquals(16, image.getOriginTop()); |
| assertEquals("clipped", getCurrentImageStateName(image)); |
| } |
| |
| @SuppressWarnings("deprecation") |
| public void testLoadListenerWiring() { |
| Image im = new Image(); |
| |
| im.addLoadListener(new LoadListener() { |
| |
| @Override |
| public void onError(Widget sender) { |
| ++firedError; |
| } |
| |
| @Override |
| public void onLoad(Widget sender) { |
| ++firedLoad; |
| } |
| }); |
| im.fireEvent(new LoadEvent() { |
| // Replaced by Joel's event firing when possible. |
| }); |
| assertEquals(1, firedLoad); |
| assertEquals(0, firedError); |
| im.fireEvent(new ErrorEvent() { |
| // Replaced by Joel's event firing when possible. |
| }); |
| assertEquals(1, firedLoad); |
| assertEquals(1, firedError); |
| } |
| |
| /** |
| * Test that attaching an image multiple times results in only one load event. |
| */ |
| public void testMultipleAttach() { |
| final Image image = new Image("counting-forwards.png"); |
| |
| final TestLoadHandler loadHandler = new TestLoadHandler() { |
| @Override |
| public void onLoad(LoadEvent event) { |
| if (isFinished()) { |
| fail("LoadHandler fired multiple times."); |
| } |
| finish(); |
| } |
| }; |
| image.addErrorHandler(new TestErrorHandler(image)); |
| image.addLoadHandler(loadHandler); |
| |
| RootPanel.get().add(image); |
| RootPanel.get().remove(image); |
| RootPanel.get().add(image); |
| RootPanel.get().remove(image); |
| RootPanel.get().add(image); |
| RootPanel.get().remove(image); |
| RootPanel.get().add(image); |
| |
| delayTestFinish(DEFAULT_TEST_TIMEOUT); |
| new Timer() { |
| @Override |
| public void run() { |
| assertTrue(loadHandler.isFinished()); |
| finishTest(); |
| } |
| }.schedule(LOAD_EVENT_TIMEOUT); |
| } |
| |
| /** |
| * Verify that detaching and reattaching an image in a handler does not fire a |
| * second onload event. |
| */ |
| public void testNoEventOnReattachInHandler() { |
| final Image image = new Image("counting-forwards.png"); |
| |
| delayTestFinish(DEFAULT_TEST_TIMEOUT); |
| image.addErrorHandler(new TestErrorHandler(image)); |
| image.addLoadHandler(new LoadHandler() { |
| private int onLoadEventCount = 0; |
| |
| @Override |
| public void onLoad(LoadEvent event) { |
| if (++onLoadEventCount == 1) { |
| RootPanel.get().remove(image); |
| RootPanel.get().add(image); |
| // The extra onLoad would will fire synchronously before finishTest(). |
| finishTest(); |
| } else { |
| fail("onLoad fired on reattach."); |
| } |
| } |
| }); |
| |
| RootPanel.get().add(image); |
| } |
| |
| public void testOneEventOnly() { |
| final Image image = new Image("counting-forwards.png"); |
| |
| final TestLoadHandler loadHandler = new TestLoadHandler() { |
| @Override |
| public void onLoad(LoadEvent event) { |
| if (isFinished()) { |
| fail("LoadHandler fired multiple times."); |
| } |
| finish(); |
| } |
| }; |
| image.addErrorHandler(new TestErrorHandler(image)); |
| image.addLoadHandler(loadHandler); |
| |
| RootPanel.get().add(image); |
| delayTestFinish(DEFAULT_TEST_TIMEOUT); |
| new Timer() { |
| @Override |
| public void run() { |
| assertTrue(loadHandler.isFinished()); |
| finishTest(); |
| } |
| }.schedule(LOAD_EVENT_TIMEOUT); |
| } |
| |
| public void testOneEventOnlyClippedImage() { |
| final Image image = new Image("counting-forwards.png", 12, 13, 8, 8); |
| |
| final TestLoadHandler loadHandler = new TestLoadHandler() { |
| @Override |
| public void onLoad(LoadEvent event) { |
| if (isFinished()) { |
| fail("LoadHandler fired multiple times."); |
| } |
| finish(); |
| } |
| }; |
| image.addErrorHandler(new TestErrorHandler(image)); |
| image.addLoadHandler(loadHandler); |
| |
| RootPanel.get().add(image); |
| delayTestFinish(DEFAULT_TEST_TIMEOUT); |
| new Timer() { |
| @Override |
| public void run() { |
| assertTrue(loadHandler.isFinished()); |
| finishTest(); |
| } |
| }.schedule(LOAD_EVENT_TIMEOUT); |
| } |
| |
| @WithProperties({ |
| @Property(name = "ClientBundle.enableInlining", value = "false") |
| }) |
| public void testResourceConstructor() { |
| Bundle b = GWT.create(Bundle.class); |
| Image image = new Image(b.prettyPiccy()); |
| assertResourceWorked(image, b.prettyPiccy()); |
| assertTrue(b.prettyPiccy() instanceof ImageResourcePrototype.Bundle); |
| assertEquals("clipped", getCurrentImageStateName(image)); |
| } |
| |
| @WithProperties({ |
| @Property(name = "ClientBundle.enableInlining", value = "false") |
| }) |
| public void testSetResource() { |
| Bundle b = GWT.create(Bundle.class); |
| Image image = new Image(); |
| image.setResource(b.prettyPiccy()); |
| assertResourceWorked(image, b.prettyPiccy()); |
| |
| assertTrue(b.prettyPiccy() instanceof ImageResourcePrototype.Bundle); |
| assertEquals("clipped", getCurrentImageStateName(image)); |
| } |
| |
| public void testStandaloneResourceConstructor() { |
| Bundle b = GWT.create(Bundle.class); |
| Image image = new Image(b.prettyPiccyStandalone()); |
| assertResourceWorked(image, b.prettyPiccyStandalone()); |
| |
| assertFalse(b.prettyPiccyStandalone() instanceof ImageResourcePrototype.Bundle); |
| assertEquals("unclipped", getCurrentImageStateName(image)); |
| } |
| |
| public void testStandaloneSetResource() { |
| Bundle b = GWT.create(Bundle.class); |
| Image image = new Image(); |
| image.setResource(b.prettyPiccyStandalone()); |
| assertResourceWorked(image, b.prettyPiccyStandalone()); |
| |
| assertFalse(b.prettyPiccyStandalone() instanceof ImageResourcePrototype.Bundle); |
| assertEquals("unclipped", getCurrentImageStateName(image)); |
| } |
| |
| /** |
| * Tests the behavior of |
| * {@link com.google.gwt.user.client.ui.Image#setUrlAndVisibleRect(String,int,int,int,int)} |
| * on a clipped image. |
| */ |
| @SuppressWarnings("deprecation") |
| public void testSetUrlAndVisibleRectOnClippedImage() { |
| final Image image = new Image("counting-backwards.png", 12, 12, 12, 12); |
| |
| final TestLoadListener listener = new TestLoadListener(image) { |
| @Override |
| public void onLoad(Widget sender) { |
| if (isFinished()) { |
| fail("LoadListener fired twice. Expected it to fire only once."); |
| } |
| |
| assertEquals(0, image.getOriginLeft()); |
| assertEquals(16, image.getOriginTop()); |
| assertEquals(16, image.getWidth()); |
| assertEquals(16, image.getHeight()); |
| assertEquals("clipped", getCurrentImageStateName(image)); |
| finish(); |
| } |
| }; |
| image.addLoadListener(listener); |
| |
| final TestLoadHandler loadHandler = new TestLoadHandler() { |
| @Override |
| public void onLoad(LoadEvent event) { |
| if (isFinished()) { |
| fail("LoadHandler fired twice. Expected it to fire only once."); |
| } |
| if (listener.isFinished()) { |
| finish(); |
| } else { |
| fail("Listener did not fire first"); |
| } |
| } |
| }; |
| image.addLoadHandler(loadHandler); |
| image.addErrorHandler(new TestErrorHandler(image)); |
| |
| RootPanel.get().add(image); |
| assertEquals("clipped", getCurrentImageStateName(image)); |
| |
| /* |
| * Change the url and visible rect, but we only expect one asynchronous load |
| * event to fire. This is consistent with the expected behavior of changing |
| * the source URL in the same event loop. |
| */ |
| image.setUrlAndVisibleRect("counting-forwards.png", 0, 16, 16, 16); |
| |
| delayTestFinish(DEFAULT_TEST_TIMEOUT); |
| new Timer() { |
| @Override |
| public void run() { |
| assertTrue(loadHandler.isFinished()); |
| finishTest(); |
| } |
| }.schedule(SYNTHETIC_LOAD_EVENT_TIMEOUT); |
| } |
| |
| /** |
| * Tests the firing of onload events when calling |
| * {@link com.google.gwt.user.client.ui.Image#setVisibleRect(int,int,int,int)} |
| * on a clipped image. |
| */ |
| @SuppressWarnings("deprecation") |
| public void testSetVisibleRectAndLoadEventsOnClippedImage() { |
| final Image image = new Image("counting-backwards.png", 16, 16, 16, 16); |
| |
| final TestLoadListener listener = new TestLoadListener(image) { |
| @Override |
| public void onLoad(Widget sender) { |
| if (isFinished()) { |
| fail("LoadListener fired twice. Expected it to fire only once."); |
| } |
| finish(); |
| } |
| }; |
| image.addLoadListener(listener); |
| |
| final TestLoadHandler loadHandler = new TestLoadHandler() { |
| @Override |
| public void onLoad(LoadEvent event) { |
| if (isFinished()) { |
| fail("LoadHandler fired twice. Expected it to fire only once."); |
| } |
| if (listener.isFinished()) { |
| finish(); |
| } else { |
| fail("Listener did not fire first"); |
| } |
| } |
| }; |
| image.addLoadHandler(loadHandler); |
| image.addErrorHandler(new TestErrorHandler(image)); |
| |
| RootPanel.get().add(image); |
| |
| /* |
| * Change the visible rect multiple times, but we only expect one |
| * asynchronous load event to fire after the final change. This is consistent |
| * with the expected behavior of changing the source URL multiple times. |
| */ |
| image.setVisibleRect(0, 0, 16, 16); |
| image.setVisibleRect(0, 0, 16, 16); |
| image.setVisibleRect(16, 0, 16, 16); |
| image.setVisibleRect(16, 8, 8, 8); |
| |
| delayTestFinish(DEFAULT_TEST_TIMEOUT); |
| new Timer() { |
| @Override |
| public void run() { |
| assertTrue(loadHandler.isFinished()); |
| finishTest(); |
| } |
| }.schedule(SYNTHETIC_LOAD_EVENT_TIMEOUT); |
| } |
| |
| /** |
| * Tests that it is possible to make a subclass of Image that can be wrapped. |
| */ |
| public void testWrapOfSubclass() { |
| String uid = Document.get().createUniqueId(); |
| DivElement div = Document.get().createDivElement(); |
| div.setInnerHTML("<img id='" + uid + "' src='counting-forwards.png'>"); |
| Document.get().getBody().appendChild(div); |
| |
| final TestImage image = TestImage.wrap(Document.get().getElementById(uid)); |
| assertNotNull(image); |
| |
| // Cleanup. |
| Document.get().getBody().appendChild(div); |
| RootPanel.detachNow(image); |
| } |
| |
| /** |
| * Tests that wrapping an existing DOM element works if you call |
| * setUrlAndVisibleRect() on it. |
| */ |
| public void testWrapThenSetUrlAndVisibleRect() { |
| String uid = Document.get().createUniqueId(); |
| DivElement div = Document.get().createDivElement(); |
| div.setInnerHTML("<img id='" + uid |
| + "' src='counting-backwards.png' width='16' height='16'>"); |
| Document.get().getBody().appendChild(div); |
| final Image image = Image.wrap(Document.get().getElementById(uid)); |
| |
| assertEquals(0, image.getOriginLeft()); |
| assertEquals(0, image.getOriginTop()); |
| assertEquals(16, image.getWidth()); |
| assertEquals(16, image.getHeight()); |
| assertEquals("unclipped", getCurrentImageStateName(image)); |
| |
| image.setUrlAndVisibleRect("counting-forwards.png", 0, 16, 16, 16); |
| assertEquals(0, image.getOriginLeft()); |
| assertEquals(16, image.getOriginTop()); |
| assertEquals(16, image.getWidth()); |
| assertEquals(16, image.getHeight()); |
| assertEquals("clipped", getCurrentImageStateName(image)); |
| } |
| |
| private void assertResourceWorked(Image image, ImageResource prettyPiccy) { |
| assertEquals(prettyPiccy.getSafeUri().asString(), image.getUrl()); |
| assertEquals(prettyPiccy.getTop(), image.getOriginTop()); |
| assertEquals(prettyPiccy.getHeight(), image.getHeight()); |
| assertEquals(prettyPiccy.getLeft(), image.getOriginLeft()); |
| assertEquals(prettyPiccy.getWidth(), image.getWidth()); |
| } |
| } |