// Copyright 2012 Google Inc. All Rights Reserved. // // 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.collide.client.ui.popup; import com.google.collide.client.ui.popup.CenterPanel.Resources; import com.google.collide.client.ui.popup.CenterPanel.View; import com.google.collide.client.util.Elements; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.junit.client.GWTTestCase; import com.google.gwt.user.client.Timer; import elemental.html.Element; /** * Tests for {@link CenterPanel}. * */ public class CenterPanelTest extends GWTTestCase { /** * The timeout allowed for deferred commands. */ private static final int DEFERRED_COMMAND_TIMEOUT = 2000; @Override public String getModuleName() { return PopupTestUtils.BUILD_MODULE_NAME; } private Element content; private CenterPanel panel; private Resources resources; private String styleGlass; private String styleGlassVisible; private String styleContent; private String styleContentVisible; private View view; public void testCreate() { // The content should be added to the content container. assertEquals(view.contentContainer, content.getParentElement()); // The popup is not showing or attached. assertFalse(panel.isShowing()); assertNull(view.popup.getParentElement()); } public void testHide() { // Show the popup. panel.show(); delayTestFinish(DEFERRED_COMMAND_TIMEOUT); Scheduler.get().scheduleDeferred(new ScheduledCommand() { @Override public void execute() { assertTrue(panel.isShowing()); // Hide the panel. Styles are removed in this event loop, but the popup // isn't detached until the animation ends. panel.hide(); assertHiding(); } }); } public void testHideThenShow() { // Show the popup. panel.show(); delayTestFinish(DEFERRED_COMMAND_TIMEOUT); Scheduler.get().scheduleDeferred(new ScheduledCommand() { @Override public void execute() { assertTrue(panel.isShowing()); panel.hide(); panel.show(); assertShowing(); } }); } public void testHideTwice() { // Show the popup. panel.show(); delayTestFinish(DEFERRED_COMMAND_TIMEOUT); Scheduler.get().scheduleDeferred(new ScheduledCommand() { @Override public void execute() { assertTrue(panel.isShowing()); // Hide the panel. Styles are removed in this event loop, but the popup // isn't detached until the animation ends. panel.hide(); panel.hide(); // No-op. assertHiding(); } }); } public void testShow() { // Initial state is detached and not visible. assertFalse(panel.isShowing()); assertTrue(view.glass.getClassName().contains(styleGlass)); assertFalse(view.glass.getClassName().contains(styleGlassVisible)); assertTrue(view.contentContainer.getClassName().contains(styleContent)); assertFalse(view.contentContainer.getClassName().contains(styleContentVisible)); assertNull(view.popup.getParentElement()); // Show the popup. The popup is attached in this event loop, but styles are // not yet added. panel.show(); assertShowing(); } /** * Tests that the panel can be shown and hidden in the same event loop. */ public void testShowThenHide() { panel.show(); panel.hide(); assertHiding(); } public void testShowTwice() { panel.show(); panel.show(); // No-op. assertShowing(); } @Override protected void gwtSetUp() throws Exception { super.gwtSetUp(); resources = GWT.create(CenterPanel.Resources.class); content = Elements.createDivElement(); content.setInnerHTML("hello world"); panel = CenterPanel.create(resources, content); view = panel.getView(); styleGlass = view.css.glass(); styleGlassVisible = view.css.glassVisible(); styleContent = view.css.content(); styleContentVisible = view.css.contentVisible(); } @Override protected void gwtTearDown() throws Exception { super.gwtTearDown(); // Remove the popup from the DOM. panel.hide(); } /** * Asserts that the panel is transitioning to a hiding state, and eventually * is removed from the DOM. This method should be called after * {@link CenterPanel#hide()} is called. */ private void assertHiding() { // Styles are removed in this event loop, but the popup isn't detached until // the animation ends. assertFalse(panel.isShowing()); assertTrue(view.glass.getClassName().contains(styleGlass)); assertFalse(view.glass.getClassName().contains(styleGlassVisible)); assertTrue(view.contentContainer.getClassName().contains(styleContent)); assertFalse(view.contentContainer.getClassName().contains(styleContentVisible)); assertNotNull(view.popup.getParentElement()); // The panel is removed from the DOM after the animation completes. int animDuration = view.getAnimationDuration(); delayTestFinish(animDuration * 2); // Reset the timeout if already async. new Timer() { @Override public void run() { assertFalse(panel.isShowing()); assertTrue(view.glass.getClassName().contains(styleGlass)); assertFalse(view.glass.getClassName().contains(styleGlassVisible)); assertTrue(view.contentContainer.getClassName().contains(styleContent)); assertFalse(view.contentContainer.getClassName().contains(styleContentVisible)); assertNull(view.popup.getParentElement()); finishTest(); } }.schedule(animDuration + 1); } /** * Asserts that the panel is transitioning to a showing state, and eventually * becomes visible. This method should be called after * {@link CenterPanel#show()} is called. */ private void assertShowing() { // The popup is attached in this event loop, but styles are not yet added. assertTrue(panel.isShowing()); assertTrue(view.glass.getClassName().contains(styleGlass)); assertFalse(view.glass.getClassName().contains(styleGlassVisible)); assertTrue(view.contentContainer.getClassName().contains(styleContent)); assertFalse(view.contentContainer.getClassName().contains(styleContentVisible)); assertNotNull(view.popup.getParentElement()); // The visible styles are added after a deferred command to ensure that the // browser respects the CSS transitions. delayTestFinish(DEFERRED_COMMAND_TIMEOUT); Scheduler.get().scheduleDeferred(new ScheduledCommand() { @Override public void execute() { assertTrue(panel.isShowing()); assertTrue(view.glass.getClassName().contains(styleGlass)); assertTrue(view.glass.getClassName().contains(styleGlassVisible)); assertTrue(view.contentContainer.getClassName().contains(styleContent)); assertTrue(view.contentContainer.getClassName().contains(styleContentVisible)); assertNotNull(view.popup.getParentElement()); finishTest(); } }); } }