package org.tessell.gwt.animation.client; /** * Implements {@link IsAnimation} for unit tests. * * By default, animations auto-finish. They assume most unit tests are * not interested in their animation functionality and so immediately * run at progress=0 and progress=1. * * For unit tests that <i>do</i> want to test the animation logic, * they should call {@link #doNotAutoFinish()} and then explicitly * {@link #tick(double)} the animation through its range of progress. */ public class StubAnimation implements IsAnimation { private AnimationLogic logic; private boolean autoFinish = true; // starts out -1, moved to 0-1 when in progress, or -2 when cancelled. Yes, janky. private double currentProgress = -1; private int requestedDuration = -1; public StubAnimation(AnimationLogic logic) { this.logic = logic; } /** For tests to manually tick the animation through its progress. */ public void tick(final double progress) { if (progress < 0 || progress > 1.0) { throw new IllegalStateException("New progress must be between 0 and 1"); } if (isCancelled()) { throw new IllegalStateException("Animation is cancelled"); } if (!isRunning()) { throw new IllegalStateException("Animation is not currently in progress"); } if (isFinished()) { throw new IllegalStateException("Animation is already finished"); } if (progress == 0.0) { logic.onStart(); } logic.onUpdate(logic.interpolate(progress)); if (progress == 1.0) { logic.onComplete(); } currentProgress = progress; } /** * Mark this instance to not auto-finish and instead wait for a unit * test to explicitly {@link #tick(double)} this to completion. */ @Override public void doNotAutoFinish() { autoFinish = false; } @Override public void run(final int duration) { requestedDuration = duration; currentProgress = 0; if (autoFinish) { tick(0); tick(1); } } public int getRequestedDuration() { return requestedDuration; } public void setRequestedDuration(int requestedDuration) { this.requestedDuration = requestedDuration; } @Override public void cancel() { currentProgress = -2; } @Override public void setNewLogic(AnimationLogic logic) { this.logic = logic; } public boolean isRunning() { return currentProgress > -1 && currentProgress < 1; } public boolean isCancelled() { return currentProgress == -2; } public boolean isFinished() { return currentProgress == 1; } }