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