/*******************************************************************************
* Copyright (c) 2007, 2014 compeople AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* compeople AG - initial API and implementation
*******************************************************************************/
package org.eclipse.riena.ui.swt.utils;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IPageListener;
import org.eclipse.ui.IPartService;
import org.eclipse.ui.IPerspectiveListener;
import org.eclipse.ui.ISelectionService;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchSite;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.WorkbenchException;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.riena.core.test.RienaTestCase;
import org.eclipse.riena.core.test.collect.UITestCase;
import org.eclipse.riena.core.util.ReflectionUtils;
import org.eclipse.riena.navigation.ISubModuleNode;
import org.eclipse.riena.navigation.ui.controllers.SubModuleController;
import org.eclipse.riena.navigation.ui.swt.views.SubModuleView;
/**
* Tests for {@link DetachedViewsManager}.
*/
@UITestCase
public class DetachedViewsManagerTest extends RienaTestCase {
private static int count = 0;
private Display display;
private Shell shell;
private DetachedViewsManager manager;
private IWorkbenchSite site;
@Override
protected void setUp() {
count = 0;
display = Display.getDefault();
shell = new Shell(display);
site = new Site(shell);
manager = new DetachedViewsManager(site);
}
@Override
protected void tearDown() {
shell.dispose();
manager.dispose();
}
public void testShowView() {
assertEquals(0, count);
manager.showView("viewOne", FTViewPart.class, SWT.TOP);
// already showing - don't create another
manager.showView("viewOne", FTViewPart.class, SWT.TOP);
assertEquals(1, count);
manager.showView("viewTwo", FTViewPart.class, SWT.BOTTOM);
assertEquals(2, count);
try {
manager.showView(" ", FTViewPart.class, 1);
fail();
} catch (final RuntimeException rex) {
ok("expected");
}
try {
manager.showView(null, FTViewPart.class, 1);
fail();
} catch (final RuntimeException rex) {
ok("expected");
}
try {
manager.showView("", FTViewPart.class, 1);
fail();
} catch (final RuntimeException rex) {
ok("expected");
}
try {
manager.showView("viewThree", null, SWT.TOP);
fail();
} catch (final RuntimeException rex) {
ok("expected");
}
try {
manager.showView("viewThree", FTViewPart.class, -1);
fail();
} catch (final RuntimeException rex) {
ok("expected");
}
}
public void testShowViewWithBounds() {
manager.showView("viewOne", FTViewPart.class, new Rectangle(20, 30, 400, 500));
final Shell shellOne = manager.getShell("viewOne");
final Rectangle shellBounds = shellOne.getBounds();
assertEquals(20, shellBounds.x);
assertEquals(30, shellBounds.y);
assertEquals(400, shellBounds.width);
assertEquals(500, shellBounds.height);
}
public void testHideView() {
manager.showView("viewOne", FTViewPart.class, SWT.TOP);
final Shell viewOne = manager.getShell("viewOne");
assertEquals(1, count);
assertTrue(viewOne.isVisible());
manager.hideView("viewOne");
assertEquals(1, count);
assertFalse(viewOne.isVisible());
assertFalse(shell.isDisposed());
manager.showView("viewOne", FTViewPart.class, SWT.TOP);
assertEquals(1, count);
assertTrue(viewOne.isVisible());
assertFalse(shell.isDisposed());
try {
manager.hideView(null);
fail();
} catch (final RuntimeException rex) {
ok("expected");
}
}
public void testCloseView() {
manager.showView("viewOne", FTViewPart.class, SWT.TOP);
manager.showView("viewTwo", FTViewPart.class, SWT.BOTTOM);
final Shell viewOne = manager.getShell("viewOne");
final Shell viewTwo = manager.getShell("viewTwo");
assertEquals(2, count);
assertTrue(viewOne.isVisible());
assertTrue(viewTwo.isVisible());
assertFalse(viewOne.isDisposed());
assertFalse(viewTwo.isDisposed());
manager.closeView("viewTwo");
assertEquals(1, count);
assertTrue(viewOne.isVisible());
assertFalse(viewOne.isDisposed());
assertTrue(viewTwo.isDisposed());
manager.closeView("viewOne");
assertEquals(0, count);
assertTrue(viewOne.isDisposed());
assertTrue(viewTwo.isDisposed());
manager.closeView("viewOne");
try {
manager.closeView(null);
fail();
} catch (final RuntimeException rex) {
ok("expected");
}
}
public void testDispose() {
manager.showView("viewOne", FTViewPart.class, SWT.TOP);
manager.showView("viewTwo", FTViewPart.class, SWT.BOTTOM);
assertEquals(2, count);
manager.dispose();
assertEquals(0, count);
}
public void testGetShell() {
assertNull(manager.getShell("viewOne"));
manager.showView("viewOne", FTViewPart.class, SWT.TOP);
final Shell shellOne = manager.getShell("viewOne");
assertNotNull(shellOne);
manager.hideView("viewOne");
assertSame(shellOne, manager.getShell("viewOne"));
manager.closeView("viewOne");
assertNull(manager.getShell("viewOne"));
try {
manager.getShell(null);
fail();
} catch (final RuntimeException rex) {
ok("expected");
}
}
public void testCreateController() {
Boolean result;
result = ReflectionUtils.invokeHidden(manager, "checkController", new FTViewPart());
assertTrue(result.booleanValue());
result = ReflectionUtils.invokeHidden(manager, "checkController", new FTViewWithController());
assertTrue(result.booleanValue());
result = ReflectionUtils.invokeHidden(manager, "checkController", new FTViewWithoutController());
assertFalse(result.booleanValue());
}
// helping classes
//////////////////
/**
* Mock implementation of {@link IWorkbenchSite}. Can return a Shell and a
* IWorkbenchWindow instance.
*/
private static final class Site implements IWorkbenchSite {
private final Shell shell;
private IWorkbenchWindow window;
public Site(final Shell shell) {
this.shell = shell;
}
public IWorkbenchPage getPage() {
return null;
}
public ISelectionProvider getSelectionProvider() {
return null;
}
public Shell getShell() {
return shell;
}
public IWorkbenchWindow getWorkbenchWindow() {
if (window == null) {
window = new WorkbenchWindow(shell);
}
return window;
}
public void setSelectionProvider(final ISelectionProvider provider) {
// unused
}
@SuppressWarnings("rawtypes")
public Object getAdapter(final Class adapter) {
return null;
}
@SuppressWarnings("rawtypes")
public Object getService(final Class api) {
return null;
}
@SuppressWarnings("rawtypes")
public boolean hasService(final Class api) {
return false;
}
}
/**
* Mock implementation of {@link IWorkbenchWindow}. Can return a Shell
* instance.
*/
private static final class WorkbenchWindow implements IWorkbenchWindow {
private final Shell shell;
public WorkbenchWindow(final Shell shell) {
this.shell = shell;
}
public boolean close() {
shell.close();
return true;
}
public IWorkbenchPage getActivePage() {
return null;
}
public IExtensionTracker getExtensionTracker() {
return null;
}
public IWorkbenchPage[] getPages() {
return null;
}
public IPartService getPartService() {
return null;
}
public ISelectionService getSelectionService() {
return null;
}
public Shell getShell() {
return shell;
}
public IWorkbench getWorkbench() {
return null;
}
public boolean isApplicationMenu(final String menuId) {
return false;
}
public IWorkbenchPage openPage(final IAdaptable input) throws WorkbenchException {
return null;
}
public IWorkbenchPage openPage(final String perspectiveId, final IAdaptable input) throws WorkbenchException {
return null;
}
public void run(final boolean fork, final boolean cancelable, final IRunnableWithProgress runnable)
throws InvocationTargetException, InterruptedException {
}
public void setActivePage(final IWorkbenchPage page) {
}
public void addPageListener(final IPageListener listener) {
}
public void addPerspectiveListener(final IPerspectiveListener listener) {
}
public void removePageListener(final IPageListener listener) {
}
public void removePerspectiveListener(final IPerspectiveListener listener) {
}
@SuppressWarnings("rawtypes")
public Object getService(final Class api) {
return null;
}
@SuppressWarnings("rawtypes")
public boolean hasService(final Class api) {
return false;
}
}
/**
* Mock implementation of a {@link ViewPart}. Will increment / decerement
* COUNT on ui-creation / ui-disposal.
* <p>
* Must be public because it is instantiated by the code under test via
* reflection.
*/
public static final class FTViewPart extends ViewPart {
@Override
public void createPartControl(final Composite parent) {
count++;
}
@Override
public void dispose() {
count--;
super.dispose();
}
@Override
public void setFocus() {
// unused
}
}
/**
* Mock implementation of a {@link SubModuleController}.
*/
public static final class FTViewController extends SubModuleController {
}
/**
* A SubModuleView that returns a controller.
*/
public static final class FTViewWithController extends SubModuleView {
private final FTViewController controller = new FTViewController();
@Override
protected FTViewController createController(final ISubModuleNode node) {
return controller;
}
@Override
protected void basicCreatePartControl(final Composite parent) {
// unused
}
}
/**
* A SubModuleView that does not return a controller.
*/
public static final class FTViewWithoutController extends SubModuleView {
@Override
protected void basicCreatePartControl(final Composite parent) {
// unused
}
}
}