blob: 1a30d4fc4b671b35c6949eb78dd60fc363c01140 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2010 IBM Corporation 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:
* IBM Corporation - initial API and implementation
******************************************************************************/
package org.eclipse.e4.core.services.internal.context;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import junit.framework.TestCase;
import org.eclipse.e4.core.services.IDisposable;
import org.eclipse.e4.core.services.context.ContextChangeEvent;
import org.eclipse.e4.core.services.context.EclipseContextFactory;
import org.eclipse.e4.core.services.context.IEclipseContext;
import org.eclipse.e4.core.services.context.IRunAndTrack;
import org.eclipse.e4.core.services.context.spi.ContextFunction;
import org.eclipse.e4.core.services.context.spi.IContextConstants;
import org.eclipse.e4.core.tests.services.TestActivator;
/**
* Tests for {@link org.eclipse.e4.core.services.context.IRunAndTrack}.
*/
public class RunAndTrackTest extends TestCase {
private class ActivePartLookupFunction extends ContextFunction {
/*
* (non-Javadoc)
*
* @see org.eclipse.e4.core.services.context.spi.ContextFunction#compute(
* org.eclipse.e4.core.services.context.IEclipseContext, java.lang.Object[])
*/
public Object compute(IEclipseContext context, Object[] arguments) {
IEclipseContext childContext = (IEclipseContext) context.getLocal(ACTIVE_CHILD);
if (childContext != null) {
return childContext.get(ACTIVE_PART);
}
return context.get(INTERNAL_LOCAL_PART);
}
}
static final String ACTIVE_CHILD = "activeChild";
static final String ACTIVE_PART = "activePart";
static final String ACTIVE_PART_ID = "activePartId";
static final String INTERNAL_LOCAL_PART = "localPart";
private List createdContexts = new ArrayList();
private IEclipseContext createContext(IEclipseContext parentContext, String level) {
IEclipseContext childContext = EclipseContextFactory.create(parentContext, null);
createdContexts.add(childContext);
childContext.set(IContextConstants.DEBUG_STRING, level);
return childContext;
}
private IEclipseContext getGlobalContext() {
IEclipseContext serviceContext = EclipseContextFactory
.getServiceContext(TestActivator.bundleContext);
// global initialization and setup, usually done by workbench
IEclipseContext appContext = createContext(serviceContext, "globalContext");
appContext.set("globalContext", appContext);
return appContext;
}
private IEclipseContext[] createNextLevel(IEclipseContext parent, String prefix, int num) {
assertTrue(num > 0);
IEclipseContext[] contexts = new IEclipseContext[num];
for (int i = 0; i < num; i++) {
contexts[i] = createContext(parent, prefix + i);
contexts[i].set(INTERNAL_LOCAL_PART, prefix + i);
}
parent.set(ACTIVE_CHILD, contexts[0]);
return contexts;
}
/*
* (non-Javadoc)
*
* @see junit.framework.TestCase#tearDown()
*/
protected void tearDown() throws Exception {
for (Iterator i = createdContexts.iterator(); i.hasNext();) {
IDisposable context = (IDisposable) i.next();
context.dispose();
}
createdContexts.clear();
super.tearDown();
}
public void testActiveChain() throws Exception {
final IEclipseContext workbenchContext = getGlobalContext();
workbenchContext.set("activePart", new ActivePartLookupFunction());
final IEclipseContext[] windows = createNextLevel(workbenchContext, "window", 1);
createNextLevel(windows[0], "part", 2);
assertEquals("part0", workbenchContext.get(ACTIVE_PART));
}
public void testActiveChange() throws Exception {
final IEclipseContext workbenchContext = getGlobalContext();
workbenchContext.set("activePart", new ActivePartLookupFunction());
final IEclipseContext[] windows = createNextLevel(workbenchContext, "window", 1);
final IEclipseContext[] parts = createNextLevel(windows[0], "part", 2);
assertEquals("part0", workbenchContext.get(ACTIVE_PART));
windows[0].set(ACTIVE_CHILD, parts[1]);
assertEquals("part1", workbenchContext.get(ACTIVE_PART));
}
/**
* Tests that {@link org.eclipse.e4.core.services.context.ContextChangeEvent#getOldValue()}
* returns the correct value for various change types.
*/
public void testContextEventOldValue() {
final String NAME = "Name";
class ContextListener implements IRunAndTrack {
public Object newValue;
public Object oldValue;
public boolean notify(ContextChangeEvent event) {
oldValue = event.getOldValue();
IEclipseContext eventsContext = event.getContext();
newValue = eventsContext.get(NAME);
return true;
}
}
IEclipseContext context = EclipseContextFactory.create();
context.set(NAME, "Value");
ContextListener listener = new ContextListener();
context.runAndTrack(listener, null);
assertEquals("Value", listener.newValue);
assertNull(listener.oldValue);
// simple value change
context.set(NAME, "NewValue");
assertEquals("Value", listener.oldValue);
assertEquals("NewValue", listener.newValue);
// set value to null
context.set(NAME, null);
assertEquals("NewValue", listener.oldValue);
assertEquals(null, listener.newValue);
// set from null to non-null
context.set(NAME, "Value");
assertEquals(null, listener.oldValue);
assertEquals("Value", listener.newValue);
// remove
context.remove(NAME);
assertEquals("Value", listener.oldValue);
assertEquals(null, listener.newValue);
}
/**
* Tests that {@link org.eclipse.e4.core.services.context.ContextChangeEvent#getOldValue()}
* returns the correct value for various change types.
*/
public void testContextEventType() {
final String NAME = "Name";
class ContextListener implements IRunAndTrack {
int eventType;
public boolean notify(ContextChangeEvent event) {
// must get a value so we aren't removed
eventType = event.getEventType();
IEclipseContext eventsContext = event.getContext();
eventsContext.get(NAME);
return true;
}
}
IEclipseContext context = EclipseContextFactory.create();
ContextListener listener = new ContextListener();
context.runAndTrack(listener, null);
assertEquals(ContextChangeEvent.INITIAL, listener.eventType);
// add a new value
context.set(NAME, "Value");
assertEquals(ContextChangeEvent.ADDED, listener.eventType);
// simple value change
context.set(NAME, "NewValue");
assertEquals(ContextChangeEvent.ADDED, listener.eventType);
// set value to null
context.set(NAME, null);
assertEquals(ContextChangeEvent.ADDED, listener.eventType);
// set from null to non-null
context.set(NAME, "Value");
assertEquals(ContextChangeEvent.ADDED, listener.eventType);
// remove
context.remove(NAME);
assertEquals(ContextChangeEvent.REMOVED, listener.eventType);
// dispose context
((IDisposable) context).dispose();
assertEquals(ContextChangeEvent.DISPOSE, listener.eventType);
}
/**
* There was a failing scenario in the legacy workbench support. This captures the hierarchy and
* function (without any workbench level references). It should be updated when we figure out
* the failing scenario :-)
*
* @throws Exception
*/
public void testRunAndTrackComplex() throws Exception {
final IEclipseContext workbenchContext = getGlobalContext();
workbenchContext.set("activePart", new ActivePartLookupFunction());
final IEclipseContext[] windows = createNextLevel(workbenchContext, "window", 1);
windows[0].runAndTrack(new IRunAndTrack() {
public boolean notify(ContextChangeEvent event) {
final Object part = windows[0].get(ACTIVE_PART);
windows[0].set(ACTIVE_PART_ID, part);
return true;
}
public String toString() {
return ACTIVE_PART_ID;
}
}, null);
final IEclipseContext[] mainSashes = createNextLevel(windows[0], "mainSash", 2);
createNextLevel(mainSashes[1], "editorArea", 1);
final IEclipseContext[] viewSashes = createNextLevel(mainSashes[0], "viewSashes", 2);
// create package explorer stack
final IEclipseContext[] packageStack = createNextLevel(viewSashes[0], "packageStack", 1);
final IEclipseContext[] packageViews = createNextLevel(packageStack[0], "packageViews", 3);
assertNotNull(packageViews);
assertEquals("packageViews0", windows[0].get(ACTIVE_PART));
assertEquals("packageViews0", windows[0].get(ACTIVE_PART_ID));
// create problems stack
final IEclipseContext[] problemsStack = createNextLevel(viewSashes[1], "problemsStack", 1);
final IEclipseContext[] problemsViews = createNextLevel(problemsStack[0], "problemViews", 5);
assertNotNull(problemsViews);
assertEquals("packageViews0", windows[0].get(ACTIVE_PART));
assertEquals("packageViews0", windows[0].get(ACTIVE_PART_ID));
assertEquals("problemViews0", problemsStack[0].get(ACTIVE_PART));
// this won't change since it is a "runAndTrack" at the window context
// level
assertEquals("packageViews0", problemsStack[0].get(ACTIVE_PART_ID));
// set the "problems view" active, propagating the information up
// the active chain.
problemsStack[0].set(ACTIVE_CHILD, problemsViews[0]);
viewSashes[1].set(ACTIVE_CHILD, problemsStack[0]);
mainSashes[0].set(ACTIVE_CHILD, viewSashes[1]);
windows[0].set(ACTIVE_CHILD, mainSashes[0]);
workbenchContext.set(ACTIVE_CHILD, windows[0]);
assertEquals("problemViews0", windows[0].get(ACTIVE_PART));
assertEquals("problemViews0", windows[0].get(ACTIVE_PART_ID));
assertEquals("packageViews0", packageStack[0].get(ACTIVE_PART));
assertEquals("problemViews0", packageStack[0].get(ACTIVE_PART_ID));
}
public void testRunAndTrackSimple() throws Exception {
final IEclipseContext workbenchContext = getGlobalContext();
workbenchContext.set("activePart", new ActivePartLookupFunction());
final IEclipseContext[] windows = createNextLevel(workbenchContext, "window", 1);
windows[0].runAndTrack(new IRunAndTrack() {
public boolean notify(ContextChangeEvent event) {
final Object part = windows[0].get(ACTIVE_PART);
windows[0].set(ACTIVE_PART_ID, part);
return true;
}
public String toString() {
return ACTIVE_PART_ID;
}
}, null);
final IEclipseContext[] parts = createNextLevel(windows[0], "part", 2);
assertEquals("part0", workbenchContext.get(ACTIVE_PART));
assertEquals("part0", windows[0].get(ACTIVE_PART_ID));
windows[0].set(ACTIVE_CHILD, parts[1]);
assertEquals("part1", windows[0].get(ACTIVE_PART));
assertEquals("part1", windows[0].get(ACTIVE_PART_ID));
}
}